20260711:1、物模型纵向计算

This commit is contained in:
zhugongping 2026-07-11 16:40:06 +08:00
parent ea8616c649
commit 95d35341ac
12 changed files with 131 additions and 50 deletions

View File

@ -8,11 +8,8 @@ TARGET_PORT = 8888 # 请根据实际情况修改
# 元数组 modbus 指令 # 元数组 modbus 指令
MODBUS_DATA_HEX = ( MODBUS_DATA_HEX = (
"7e80DD33D43DFC5B7e", "7e80D20C4C6A55D57e",
"010320413d0d7541bacb2dbf42019a3f6bdb33c2b19c73c0d39f304100a253c3f9f2187f3a", "01030400110018AA3C"
"020320414056d541b8ad60c02d4acd3fa708cdc2adfe5ac1bcf64c413630c4c3f9a81af11d",
"030320413fc48241b919bcc0006ecd3ff874cdc2ae6c0ac18c11e041877c67c3f9b431a049",
"040320413f56c341b0362ebf48b333403e3200c2addb5cc0daec4341cf60bdc3f9a40fae0b"
) )
# 深部位移计 # 深部位移计

View File

@ -133,7 +133,7 @@ public class CRC16Utils {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
String hex = "006000000000"; String hex = "01030400110018AA3C";
byte[] bytes = ByteUtils.hexToByte(hex); byte[] bytes = ByteUtils.hexToByte(hex);
String crc = getCRC(bytes); String crc = getCRC(bytes);
System.out.println(crc); System.out.println(crc);

View File

@ -363,7 +363,7 @@ public class TSLCacheImpl implements ITSLCache {
// 从数据库查询设备级计算物模型 // 从数据库查询设备级计算物模型
ThingsModel model = new ThingsModel(); ThingsModel model = new ThingsModel();
model.setSerialNumber(serialNumber); model.setSerialNumber(serialNumber);
model.setIsCalculated(1); // 查询设备级物模型 model.setIsCalculatedList(Arrays.asList(1,2)); // 查询设备级物模型
List<ThingsModel> models = thingsModelService.selectThingsModelList(model); List<ThingsModel> models = thingsModelService.selectThingsModelList(model);
if (CollectionUtils.isEmpty(models)) { if (CollectionUtils.isEmpty(models)) {
// 清除可能存在的旧缓存 // 清除可能存在的旧缓存

View File

@ -109,12 +109,14 @@ public class ThingsModel extends BaseEntity {
private String formula; private String formula;
/** /**
* 物模型来源类型(0-设备上报,1-纯计算,2-其他预留) * 物模型来源类型(0-设备上报,1-纯计算(横向计算),2-纵向计算)
* 纯计算物模型:计算公式包含{},依赖其他物模型计算值 * 纯计算物模型:计算公式包含{},依赖其他物模型计算值
*/ */
@ApiModelProperty(value = "物模型来源类型", notes = "(0-设备上报,1-纯计算,2-其他预留)") @ApiModelProperty(value = "物模型来源类型", notes = "(0-设备上报,1-纯计算(横向计算),2-纵向计算)")
private Integer isCalculated; private Integer isCalculated;
private List<Integer> isCalculatedList;
/** /**
* 数据定义 * 数据定义
*/ */

View File

@ -81,7 +81,7 @@ public class ThingsModelValueItem {
private String formula; private String formula;
/** /**
* 物模型来源类型(0-设备上报,1-纯计算,2-其他预留) * 物模型来源类型(0-设备上报,1-纯计算(横向计算),2-纵向计算)
*/ */
private Integer isCalculated; private Integer isCalculated;

View File

@ -102,9 +102,7 @@ public class DcpPlatformAdapter {
try { try {
String pushPath = resolvePushPath(mapping, pushInterface); String pushPath = resolvePushPath(mapping, pushInterface);
handleNormalPush( handleNormalPush(platform, mapping, reportSerialNumber, payload, pushPath, interfaceCode, requestSchema);
platform, mapping, reportSerialNumber, payload, pushPath,
interfaceCode, requestSchema);
} catch (Exception e) { } catch (Exception e) {
String serialNumber = StringUtils.hasText(reportSerialNumber) String serialNumber = StringUtils.hasText(reportSerialNumber)
? reportSerialNumber : mapping.getSerialNumber(); ? reportSerialNumber : mapping.getSerialNumber();
@ -151,8 +149,7 @@ public class DcpPlatformAdapter {
// 无数组字段 → 简单推送,使用子设备 platformDeviceId 和主表 fieldMapping // 无数组字段 → 简单推送,使用子设备 platformDeviceId 和主表 fieldMapping
if (!hasArrayField(requestSchema)) { if (!hasArrayField(requestSchema)) {
// 如果只有一个设备完全可以走 // 如果只有一个设备完全可以走
handleSubDeviceSimplePush(platform, mapping, subMapping, reportSerialNumber, handleSubDeviceSimplePush(platform, mapping, subMapping, reportSerialNumber, payload, pushPath, interfaceCode, requestSchema);
payload, pushPath, interfaceCode, requestSchema);
return; return;
} }
@ -348,12 +345,10 @@ public class DcpPlatformAdapter {
int replayCount = 0; int replayCount = 0;
for (PlatformDeviceSubMapping monitor : subMappings) { for (PlatformDeviceSubMapping monitor : subMappings) {
if (monitor == null || !monitor.isMonitor() if (monitor == null || !monitor.isMonitor() || !StringUtils.hasText(monitor.getSubSerialNumber())) {
|| !StringUtils.hasText(monitor.getSubSerialNumber())) {
continue; continue;
} }
JSONObject monitorData = bufferService.getMonitorDataIfFresh( JSONObject monitorData = bufferService.getMonitorDataIfFresh(platform.getId(), fieldName, monitor.getSubSerialNumber(), reportIntervalSec);
platform.getId(), fieldName, monitor.getSubSerialNumber(), reportIntervalSec);
if (monitorData == null) { if (monitorData == null) {
continue; continue;
} }
@ -379,8 +374,7 @@ public class DcpPlatformAdapter {
JSONArray pushBody = buildArrayPushBody(mapping, bodyFields, fieldName, JSONArray pushBody = buildArrayPushBody(mapping, bodyFields, fieldName,
sensorData, monitor.getPlatformDeviceId()); sensorData, monitor.getPlatformDeviceId());
PlatformPushLog logEntry = createLogEntry(platform, mapping, interfaceCode, PlatformPushLog logEntry = createLogEntry(platform, mapping, interfaceCode, monitor.getSubSerialNumber());
monitor.getSubSerialNumber());
doHttpPost(platform, baseUrl, JSON.toJSONString(pushBody), logEntry); doHttpPost(platform, baseUrl, JSON.toJSONString(pushBody), logEntry);
pushLogService.asyncSave(logEntry); pushLogService.asyncSave(logEntry);
if (logEntry.getStatus() != null && logEntry.getStatus() == 1) { if (logEntry.getStatus() != null && logEntry.getStatus() == 1) {
@ -1117,8 +1111,7 @@ public class DcpPlatformAdapter {
} }
if (currentIndex == -1) { if (currentIndex == -1) {
log.warn("[DCP] 当前子设备 {} 不在监测点列表中 mappingId={}", log.warn("[DCP] 当前子设备 {} 不在监测点列表中 mappingId={}", reportSerialNumber, mapping.getId());
reportSerialNumber, mapping.getId());
return; return;
} }
@ -1156,8 +1149,7 @@ public class DcpPlatformAdapter {
} }
String sensorId = resolveSubDeviceSensorId(sub); String sensorId = resolveSubDeviceSensorId(sub);
JSONObject sensorDataItem = buildArrayItem( JSONObject sensorDataItem = buildArrayItem(platform, mapping, requestSchema, reportData, fieldName, itemFieldMappings, sensorId);
platform, mapping, requestSchema, reportData, fieldName, itemFieldMappings, sensorId);
if (sensorDataItem == null || sensorDataItem.isEmpty()) { if (sensorDataItem == null || sensorDataItem.isEmpty()) {
log.warn("[DCP] 子设备 {} 数据映射为空,跳过其 sensorData", subSn); log.warn("[DCP] 子设备 {} 数据映射为空,跳过其 sensorData", subSn);
continue; continue;

View File

@ -691,9 +691,8 @@ public class DeviceServiceImpl implements IDeviceService {
log.warn("=>查询物模型为空[{}],标识符:[{}]", input.getProductId(), identity); log.warn("=>查询物模型为空[{}],标识符:[{}]", input.getProductId(), identity);
continue; // 跳过当前物模型的处理 continue; // 跳过当前物模型的处理
} }
// 获取设备实时值 // 获取设备上一次缓存值
ValueItem cacheIdentifier = itslValueCache.getCacheIdentifier(input.getProductId(), serialNumber, ValueItem cacheIdentifier = itslValueCache.getCacheIdentifier(input.getProductId(), serialNumber, thingModels.getId());
thingModels.getId());
if (Objects.isNull(cacheIdentifier)) { if (Objects.isNull(cacheIdentifier)) {
log.warn("=>查询物模型值为空[{}],标识符:[{}]", input.getProductId(), identity); log.warn("=>查询物模型值为空[{}],标识符:[{}]", input.getProductId(), identity);
} }
@ -720,8 +719,13 @@ public class DeviceServiceImpl implements IDeviceService {
if (refValue != null && !refValue.isEmpty()) { if (refValue != null && !refValue.isEmpty()) {
params.put("{" + refIdentifier + "}", refValue); params.put("{" + refIdentifier + "}", refValue);
} else { } else {
params.put("{" + refIdentifier + "}", "0"); // 纵向计算物模型
log.warn("=>计算公式引用的物模型值不存在[{}],标识符:[{}],使用默认值0", input.getProductId(), refIdentifier); if (Integer.valueOf(2).equals(thingModels.getIsCalculated())) {
params.put("{" + refIdentifier + "}", cacheIdentifier.getValue());
} else {
params.put("{" + refIdentifier + "}", "0");
log.warn("=>计算公式引用的物模型值不存在[{}],标识符:[{}],使用默认值0", input.getProductId(), refIdentifier);
}
} }
} }
} }

View File

@ -144,6 +144,12 @@
<if test="isCalculated != null "> <if test="isCalculated != null ">
AND is_calculated = #{isCalculated} AND is_calculated = #{isCalculated}
</if> </if>
<if test="isCalculatedList != null ">
AND is_calculated IN
<foreach collection="isCalculatedList" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</if>
<if test="modelIdList != null "> <if test="modelIdList != null ">
model_id IN model_id IN
<foreach collection="modelIdList" item="item" separator="," open="(" close=")"> <foreach collection="modelIdList" item="item" separator="," open="(" close=")">

View File

@ -12,7 +12,7 @@ VUE_APP_BASE_API = /dev-api
VUE_APP_SERVER_API_URL = http://localhost:8080 VUE_APP_SERVER_API_URL = http://localhost:8080
# MQTT WebSocket 服务器地址 # MQTT WebSocket 服务器地址
VUE_APP_MQTT_SERVER_URL = ws://localhost:8083/mqtt VUE_APP_MQTT_SERVER_URL = ws://47.121.180.229:8083/mqtt
# 百度地图 API Key # 百度地图 API Key
VUE_APP_BAI_DU_AK = s9mUXN9a7bKgVu6U6Z3bXhKSxtz97YPI VUE_APP_BAI_DU_AK = s9mUXN9a7bKgVu6U6Z3bXhKSxtz97YPI

View File

@ -21,6 +21,13 @@
<el-table v-loading="loading" :data="modelList" size="mini" :border="false"> <el-table v-loading="loading" :data="modelList" size="mini" :border="false">
<el-table-column label="物模型名称" align="center" prop="modelName" width="200" /> <el-table-column label="物模型名称" align="center" prop="modelName" width="200" />
<el-table-column label="标识符" align="center" prop="identifier" /> <el-table-column label="标识符" align="center" prop="identifier" />
<el-table-column label="计算类型" align="center" width="90">
<template slot-scope="scope">
<el-tag :type="scope.row.isCalculated === 2 ? 'warning' : 'primary'" size="mini">
{{ scope.row.isCalculated === 2 ? '纵向累计' : '横向计算' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="图表展示" align="center" width="80"> <el-table-column label="图表展示" align="center" width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isChart" /> <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isChart" />
@ -80,6 +87,22 @@
<el-form-item label="排序" prop="modelOrder"> <el-form-item label="排序" prop="modelOrder">
<el-input v-model="form.modelOrder" placeholder="请输入排序" type="number" style="width: 580px" /> <el-input v-model="form.modelOrder" placeholder="请输入排序" type="number" style="width: 580px" />
</el-form-item> </el-form-item>
<el-form-item label="计算类型" prop="isCalculated">
<el-radio-group v-model="form.isCalculated">
<el-radio :label="1">
横向计算
<el-tooltip content="使用同一批上报数据中的物模型值计算" placement="top">
<i class="el-icon-question" style="color:#909399;margin-left:5px;cursor:help;"></i>
</el-tooltip>
</el-radio>
<el-radio :label="2">
纵向累计
<el-tooltip content="使用目标物模型缓存值 + 本次源物模型上报值" placement="top">
<i class="el-icon-question" style="color:#909399;margin-left:5px;cursor:help;"></i>
</el-tooltip>
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="模型特性" prop="property"> <el-form-item label="模型特性" prop="property">
<el-checkbox name="isChart" label="图表展示" v-model="form.isChart" :true-label="1" :false-label="0"></el-checkbox> <el-checkbox name="isChart" label="图表展示" v-model="form.isChart" :true-label="1" :false-label="0"></el-checkbox>
<el-checkbox name="isMonitor" label="实时监测" v-model="form.isMonitor" :true-label="1" :false-label="0"></el-checkbox> <el-checkbox name="isMonitor" label="实时监测" v-model="form.isMonitor" :true-label="1" :false-label="0"></el-checkbox>
@ -130,12 +153,14 @@
<span slot="label">{{$t('device.device-edit.148398-83')}}</span> <span slot="label">{{$t('device.device-edit.148398-83')}}</span>
<el-tooltip style="cursor: pointer" effect="light" placement="top"> <el-tooltip style="cursor: pointer" effect="light" placement="top">
<div slot="content"> <div slot="content">
用于对原始值进行计算后存储和显示<br /> 横向计算:使用同一批上报数据中的物模型值<br />
纵向累计:使用 {last} 表示当前物模型上一次缓存累计值<br />
公式中使用产品物模型标识符,并用大括号包裹<br /> 公式中使用产品物模型标识符,并用大括号包裹<br />
支持运算符:+ - * / % ^(次方) sqrt(开方)<br /> 支持运算符:+ - * / % ^(次方) sqrt(开方)<br />
<br /> <br />
<strong>示例:</strong><br /> <strong>示例:</strong><br />
压力=K*频率平方-常数:1.5*{frequency}^2-100 横向计算:1.5*{frequency}^2-100<br />
纵向累计:{last}+{rain}
</div> </div>
<i class="el-icon-question" /> <i class="el-icon-question" />
</el-tooltip> </el-tooltip>
@ -158,8 +183,24 @@
</div> </div>
<!-- 物模型变量区域:网关设备按从机展示,便于插值计算 --> <!-- 物模型变量区域:网关设备按从机展示,便于插值计算 -->
<div class="variable-section" v-loading="loadingModels"> <div class="variable-section" v-loading="loadingModels">
<span class="section-label">{{ isGatewayDevice ? '从机物模型变量(点击插入,用于跨设备插值如 从机1-从机2):' : '产品通用物模型变量:' }}</span> <span class="section-label">{{ form.isCalculated === 2 ? '纵向累计变量:' : (isGatewayDevice ? '从机物模型变量(点击插入,用于跨设备插值如 从机1-从机2):' : '产品通用物模型变量:') }}</span>
<template v-if="isGatewayDevice && gatewayVariableGroups.length"> <div v-if="form.isCalculated === 2" class="variable-tags">
<el-tag size="small" type="warning" effect="plain" class="var-tag" @click="insertVariable('last')" title="{last}">上次累计值</el-tag>
<el-tag
v-for="model in productModels"
:key="model.identifier"
size="small"
type="primary"
effect="plain"
class="var-tag"
@click="setVerticalFormula(model.identifier)"
:title="`{last}+{${model.identifier}}`"
>
{{ model.modelName }}
</el-tag>
<span v-if="productModels.length === 0 && !loadingModels" class="no-data">暂无可用物模型</span>
</div>
<template v-else-if="isGatewayDevice && gatewayVariableGroups.length">
<div v-for="grp in gatewayVariableGroups" :key="grp.slaveId" class="variable-group"> <div v-for="grp in gatewayVariableGroups" :key="grp.slaveId" class="variable-group">
<span class="group-label">从机{{ grp.slaveId }}:</span> <span class="group-label">从机{{ grp.slaveId }}:</span>
<el-tag <el-tag
@ -194,7 +235,7 @@
</div> </div>
<!-- 输入框和清空按钮 --> <!-- 输入框和清空按钮 -->
<div class="formula-input-section"> <div class="formula-input-section">
<el-input ref="formulaInput" v-model="form.formula" type="textarea" :rows="2" placeholder="输入或点击上方运算符、物模型变量构建公式" class="formula-input" /> <el-input ref="formulaInput" v-model="form.formula" type="textarea" :rows="2" :placeholder="form.isCalculated === 2 ? '请选择源物模型生成累计公式,如:{last}+{rain}' : '输入或点击上方运算符、物模型变量构建公式'" class="formula-input" />
<el-button type="danger" plain size="small" title="清空公式" @click="clearFormula" class="clear-btn">清空</el-button> <el-button type="danger" plain size="small" title="清空公式" @click="clearFormula" class="clear-btn">清空</el-button>
</div> </div>
</div> </div>
@ -241,6 +282,12 @@
font-weight: 500; font-weight: 500;
} }
.form-tip {
margin-top: 6px;
font-size: 12px;
color: #909399;
}
.operator-buttons { .operator-buttons {
display: flex; display: flex;
flex-wrap: nowrap; flex-wrap: nowrap;
@ -427,7 +474,6 @@ export default {
queryParams: { queryParams: {
productId: 0, productId: 0,
deviceId: 0, deviceId: 0,
isCalculated: 1,
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
}, },
@ -468,6 +514,7 @@ export default {
{ pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, message: '以字母开头,只含字母、数字、下划线', trigger: 'blur' }, { pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, message: '以字母开头,只含字母、数字、下划线', trigger: 'blur' },
], ],
datatype: [{ required: true, message: '请选择数据类型', trigger: 'change' }], datatype: [{ required: true, message: '请选择数据类型', trigger: 'change' }],
isCalculated: [{ required: true, message: '请选择计算类型', trigger: 'change' }],
formula: [ formula: [
{ required: true, message: '请输入计算公式', trigger: 'none' }, { required: true, message: '请输入计算公式', trigger: 'none' },
{ validator: this.validateFormula, trigger: 'none' }, { validator: this.validateFormula, trigger: 'none' },
@ -515,12 +562,25 @@ export default {
// 2. 校验变量格式:{标识符} 或 {slaveId:数字.标识符}(跨设备) // 2. 校验变量格式:{标识符} 或 {slaveId:数字.标识符}(跨设备)
const variablePattern = /\{([^}]*)\}/g; const variablePattern = /\{([^}]*)\}/g;
let match; let match;
const variableNames = [];
const simpleVar = /^[a-zA-Z][a-zA-Z0-9_]*$/; const simpleVar = /^[a-zA-Z][a-zA-Z0-9_]*$/;
const crossVar = /^slaveId:\d+\.[a-zA-Z][a-zA-Z0-9_]*$/; const crossVar = /^slaveId:\d+\.[a-zA-Z][a-zA-Z0-9_]*$/;
while ((match = variablePattern.exec(formula)) !== null) { while ((match = variablePattern.exec(formula)) !== null) {
const varName = match[1]; const varName = match[1];
variableNames.push(varName);
if (!simpleVar.test(varName) && !crossVar.test(varName)) { if (!simpleVar.test(varName) && !crossVar.test(varName)) {
callback(new Error(`变量格式错误: {${varName}}。支持:{标识符} 或 {slaveId:从机号.标识符}(如 {slaveId:1.WaterH})`)); callback(new Error(`变量格式错误: {${varName}}。支持:{标识符}、{last} 或 {slaveId:从机号.标识符}(如 {slaveId:1.WaterH})`));
return;
}
}
if (this.form.isCalculated === 2) {
if (!variableNames.includes('last')) {
callback(new Error('纵向累计公式必须包含 {last}'));
return;
}
const sourceVariables = variableNames.filter((name) => name !== 'last' && name !== this.form.identifier);
if (sourceVariables.length !== 1) {
callback(new Error('纵向累计公式必须且只能包含一个源物模型变量,如:{last}+{rain}'));
return; return;
} }
} }
@ -625,7 +685,15 @@ export default {
placeholder: `{slaveId:${g.slaveId}.${m.identifier}}`, placeholder: `{slaveId:${g.slaveId}.${m.identifier}}`,
})), })),
})); }));
this.productModels = []; return listModel({
productId: this.device.productId,
deviceId: 0,
pageNum: 1,
pageSize: 200,
});
})
.then((response) => {
this.productModels = (response.rows || []).filter((m) => m.isCalculated !== 1 && m.isCalculated !== 2);
}) })
.finally(() => { .finally(() => {
this.loadingModels = false; this.loadingModels = false;
@ -643,7 +711,7 @@ export default {
pageSize: 200, pageSize: 200,
}) })
.then((response) => { .then((response) => {
this.productModels = (response.rows || []).filter((m) => m.isCalculated !== 1); this.productModels = (response.rows || []).filter((m) => m.isCalculated !== 1 && m.isCalculated !== 2);
}) })
.finally(() => { .finally(() => {
this.loadingModels = false; this.loadingModels = false;
@ -731,6 +799,11 @@ export default {
: `{${identifierOrPlaceholder}}`; : `{${identifierOrPlaceholder}}`;
this.insertAtCursor(text); this.insertAtCursor(text);
}, },
/** 纵向累计直接生成标准公式 */
setVerticalFormula(identifier) {
this.form.formula = `{last}+{${identifier}}`;
this.focusFormulaInput();
},
/** 在光标位置插入内容(支持替换选中文本) */ /** 在光标位置插入内容(支持替换选中文本) */
insertAtCursor(text) { insertAtCursor(text) {
const input = this.$refs.formulaInput; const input = this.$refs.formulaInput;
@ -816,7 +889,6 @@ export default {
// 格式化specs // 格式化specs
this.form.specs = this.formatThingsSpecs(); this.form.specs = this.formatThingsSpecs();
this.form.isCalculated = 1;
this.form.isReadonly = 1; this.form.isReadonly = 1;
this.form.type = 1; this.form.type = 1;
// 去除公式中的空格 // 去除公式中的空格

View File

@ -96,7 +96,9 @@
<el-col :span="8"> <el-col :span="8">
<el-form-item label="批量推送"> <el-form-item label="批量推送">
<el-switch v-model="form.isBatchPush" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否" /> <el-switch v-model="form.isBatchPush" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否" />
<div style="font-size:12px;color:#909399;margin-top:4px">开启后一次请求推送全量子设备数据</div> <el-tooltip content="开启后一次请求推送全量子设备数据" placement="top">
<i class="el-icon-question" style="color:#909399;margin-left:5px;cursor:help;"></i>
</el-tooltip>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>

View File

@ -140,7 +140,7 @@
<el-input v-model="form.serialNumber" disabled /> <el-input v-model="form.serialNumber" disabled />
</el-form-item> </el-form-item>
<el-form-item label="设备名称"> <el-form-item label="设备名称">
<el-input v-model="form.deviceName" disabled /> <el-input v-model="form.deviceName" />
</el-form-item> </el-form-item>
<el-form-item label="传感器类型" prop="sensorType"> <el-form-item label="传感器类型" prop="sensorType">
<el-select v-model="form.sensorType" placeholder="选择或输入设备类型" filterable allow-create default-first-option style="width:100%"> <el-select v-model="form.sensorType" placeholder="选择或输入设备类型" filterable allow-create default-first-option style="width:100%">
@ -165,13 +165,19 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item label="推送模式" prop="pushMode"> <el-form-item label="推送模式" prop="pushMode">
<el-radio-group v-model="form.pushMode"> <el-radio-group v-model="form.pushMode">
<el-radio :label="1">实时推送</el-radio> <el-radio :label="1">
<el-radio :label="2">定时推送</el-radio> 实时推送
<el-tooltip content="设备上报即刻推送" placement="top">
<i class="el-icon-question" style="color:#909399;margin-left:5px;cursor:help;"></i>
</el-tooltip>
</el-radio>
<el-radio :label="2">
定时推送
<el-tooltip content="按间隔推送最新数据" placement="top">
<i class="el-icon-question" style="color:#909399;margin-left:5px;cursor:help;"></i>
</el-tooltip>
</el-radio>
</el-radio-group> </el-radio-group>
<div style="font-size:12px;color:#909399;margin-top:4px;line-height:1.5">
实时:设备上报即刻推送<br>
定时:按间隔推送最新数据
</div>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" v-if="form.pushMode === 2"> <el-col :span="12" v-if="form.pushMode === 2">
@ -589,7 +595,7 @@ export default {
this.deviceOptions = [{ deviceId: device.deviceId, deviceName: device.deviceName, serialNumber: device.serialNumber }] this.deviceOptions = [{ deviceId: device.deviceId, deviceName: device.deviceName, serialNumber: device.serialNumber }]
this.form.deviceId = device.deviceId this.form.deviceId = device.deviceId
this.form.serialNumber = device.serialNumber this.form.serialNumber = device.serialNumber
this.form.deviceName = device.deviceName || device.serialNumber this.form.deviceName = this.form.deviceName || device.deviceName || device.serialNumber
this.loadThingsModel(device.deviceId) this.loadThingsModel(device.deviceId)
this.loadSubDeviceOptions(device) this.loadSubDeviceOptions(device)
}).catch(() => { }).catch(() => {