20260130:设备调试页面新增产品常用指令

This commit is contained in:
George 2026-01-30 22:13:57 +08:00
parent 56cc5bce82
commit dd610bc303
5 changed files with 78 additions and 8 deletions

View File

@ -61,7 +61,8 @@ public class TCPMessageAdapter extends ChannelInboundHandlerAdapter {
session.access(); session.access();
// 快速响应匹配:串行发送场景,同一时刻只有一个等待请求 // 快速响应匹配:串行发送场景,同一时刻只有一个等待请求
if (session.hasPendingRequest() && session.response(buf.retainedDuplicate())) { int messageId = buf.getUnsignedByte(1);
if (messageId == 0x06 && session.hasPendingRequest() && session.response(buf.retainedDuplicate())) {
log.debug("=>设备响应匹配成功,设备:{}", session.getClientId()); log.debug("=>设备响应匹配成功,设备:{}", session.getClientId());
buf.release(); // 释放原始 ByteBuf buf.release(); // 释放原始 ByteBuf
return; // 直接返回,不传递到后续处理器 return; // 直接返回,不传递到后续处理器

View File

@ -56,6 +56,13 @@ public class CommandPreferences {
@ApiModelProperty("设备编号") @ApiModelProperty("设备编号")
private String serialNumber; private String serialNumber;
/**
* 产品ID(有值表示产品指令,为空时通过serialNumber判断为设备指令)
*/
@Excel(name = "产品ID")
@ApiModelProperty("产品ID")
private Long productId;
@Setter @Setter
@TableField(exist = false) @TableField(exist = false)
@ApiModelProperty("请求参数") @ApiModelProperty("请求参数")

View File

@ -9,10 +9,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="name" column="name" /> <result property="name" column="name" />
<result property="command" column="command" /> <result property="command" column="command" />
<result property="serialNumber" column="serial_number" /> <result property="serialNumber" column="serial_number" />
<result property="productId" column="product_id" />
</resultMap> </resultMap>
<sql id="selectCommandPreferencesVo"> <sql id="selectCommandPreferencesVo">
select id, name, command, serial_number from command_preferences select id, name, command, serial_number, product_id from command_preferences
</sql> </sql>
<select id="selectCommandPreferencesList" parameterType="com.fastbee.iot.domain.CommandPreferences" resultMap="CommandPreferencesResult"> <select id="selectCommandPreferencesList" parameterType="com.fastbee.iot.domain.CommandPreferences" resultMap="CommandPreferencesResult">
@ -20,8 +21,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<where> <where>
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if> <if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
<if test="command != null and command != ''"> and command = #{command}</if> <if test="command != null and command != ''"> and command = #{command}</if>
<if test="serialNumber != null and serialNumber != ''"> and serial_number = #{serialNumber}</if> <!-- 同时查询产品指令和设备指令 -->
<if test="serialNumber != null and serialNumber != '' and productId != null">
and (serial_number = #{serialNumber} or product_id = #{productId})
</if>
<!-- 仅查询设备指令 -->
<if test="serialNumber != null and serialNumber != '' and productId == null">
and serial_number = #{serialNumber}
</if>
<!-- 仅查询产品指令 -->
<if test="serialNumber == null and productId != null">
and product_id = #{productId}
</if>
</where> </where>
order by product_id asc, id desc
</select> </select>
<select id="selectCommandPreferencesById" parameterType="Long" resultMap="CommandPreferencesResult"> <select id="selectCommandPreferencesById" parameterType="Long" resultMap="CommandPreferencesResult">
@ -36,12 +49,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="name != null and name != ''">name,</if> <if test="name != null and name != ''">name,</if>
<if test="command != null and command != ''">command,</if> <if test="command != null and command != ''">command,</if>
<if test="serialNumber != null and serialNumber != ''">serial_number,</if> <if test="serialNumber != null and serialNumber != ''">serial_number,</if>
<if test="productId != null">product_id,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if> <if test="id != null">#{id},</if>
<if test="name != null and name != ''">#{name},</if> <if test="name != null and name != ''">#{name},</if>
<if test="command != null and command != ''">#{command},</if> <if test="command != null and command != ''">#{command},</if>
<if test="serialNumber != null and serialNumber != ''">#{serialNumber},</if> <if test="serialNumber != null and serialNumber != ''">#{serialNumber},</if>
<if test="productId != null">#{productId},</if>
</trim> </trim>
</insert> </insert>
@ -51,6 +66,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="name != null and name != ''">name = #{name},</if> <if test="name != null and name != ''">name = #{name},</if>
<if test="command != null and command != ''">command = #{command},</if> <if test="command != null and command != ''">command = #{command},</if>
<if test="serialNumber != null and serialNumber != ''">serial_number = #{serialNumber},</if> <if test="serialNumber != null and serialNumber != ''">serial_number = #{serialNumber},</if>
<if test="productId != null">product_id = #{productId},</if>
</trim> </trim>
where id = #{id} where id = #{id}
</update> </update>

View File

@ -44,3 +44,17 @@ ALTER TABLE `iot_things_model`
-- 3. 添加索引(设备编号索引) -- 3. 添加索引(设备编号索引)
ALTER TABLE `iot_things_model` ADD INDEX `idx_calculated_serial` (`is_calculated`, `serial_number`); ALTER TABLE `iot_things_model` ADD INDEX `idx_calculated_serial` (`is_calculated`, `serial_number`);
-- ==============================================================================
-- 日期:2026-01-30
-- 1. 添加产品ID字段
ALTER TABLE command_preferences ADD COLUMN product_id BIGINT(20) DEFAULT NULL COMMENT '产品ID' AFTER serial_number;
-- 2. 为产品ID添加索引,提升查询性能
CREATE INDEX idx_command_preferences_product_id ON command_preferences(product_id);
-- 说明:
-- product_id 有值 → 产品指令(同类产品的所有设备通用)
-- serial_number 有值 → 设备指令(仅当前设备可见)
-- 查询时通过 serial_number 或 product_id 字段是否有值来区分指令类型

View File

@ -85,7 +85,12 @@
<el-col :span="4" class="right"> <el-col :span="4" class="right">
<div class="head right-head">{{ $t('device.instruction-parsing.830424-15') }}</div> <div class="head right-head">{{ $t('device.instruction-parsing.830424-15') }}</div>
<div class="content beautify-scroll-def"> <div class="content beautify-scroll-def">
<div v-for="(item, index) in quickParsing" :key="index" class="quick-item" @click.stop="quickClick(item)" @contextmenu.prevent="onContextmenu($event, item)"> <div v-for="(item, index) in quickParsing" :key="index"
class="quick-item"
:class="{ 'product-command': item.productId != null }"
@click.stop="quickClick(item)"
@contextmenu.prevent="onContextmenu($event, item)">
<!-- <el-tag v-if="item.productId != null" size="mini" type="success" style="margin-right: 4px;">产品</el-tag>-->
{{ item.name }} {{ item.name }}
</div> </div>
</div> </div>
@ -352,6 +357,12 @@
<el-form-item :label="$t('device.instruction-parsing.830424-31')"> <el-form-item :label="$t('device.instruction-parsing.830424-31')">
<el-input v-model="editNameForm.command" style="width: 60%"></el-input> <el-input v-model="editNameForm.command" style="width: 60%"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="指令范围">
<el-radio-group v-model="editNameForm.isProductCommand">
<el-radio :label="true">产品指令(同类产品通用)</el-radio>
<el-radio :label="false">设备指令(仅本设备)</el-radio>
</el-radio-group>
</el-form-item>
</el-form> </el-form>
</div> </div>
<div slot="footer" class="dialog-btn"> <div slot="footer" class="dialog-btn">
@ -604,8 +615,10 @@ export default {
/**打开编辑名字的框 */ /**打开编辑名字的框 */
openEditName(item) { openEditName(item) {
this.editNameForm = { this.editNameForm = {
id: item.id,
name: item.name || '', name: item.name || '',
command: item.command, command: item.command,
isProductCommand: item.productId != null, // 通过 productId 判断是否为产品指令
}; };
this.editName = true; this.editName = true;
this.editDialog = true; this.editDialog = true;
@ -712,18 +725,23 @@ export default {
if (this.editName) { if (this.editName) {
try { try {
this.saveLoading = true; this.saveLoading = true;
// 根据选择决定传 productId 还是 serialNumber
const isProductCommand = this.editNameForm.isProductCommand;
if (this.editNameForm.id) { if (this.editNameForm.id) {
await editPreferences({ await editPreferences({
command: this.editNameForm.command, command: this.editNameForm.command,
name: this.editNameForm.name, name: this.editNameForm.name,
serialNumber: this.device.serialNumber, serialNumber: isProductCommand ? null : this.device.serialNumber,
productId: isProductCommand ? this.device.productId : null,
id: this.editNameForm.id, id: this.editNameForm.id,
}); });
} else { } else {
await addPreferences({ await addPreferences({
command: this.editNameForm.command, command: this.editNameForm.command,
name: this.editNameForm.name, name: this.editNameForm.name,
serialNumber: this.device.serialNumber, serialNumber: isProductCommand ? null : this.device.serialNumber,
productId: isProductCommand ? this.device.productId : null,
}); });
} }
this.$message({ this.$message({
@ -744,10 +762,13 @@ export default {
this.saveLoading = false; this.saveLoading = false;
this.editDialog = false; this.editDialog = false;
}, },
/**获取指令列表 */ /**获取指令列表(产品指令+设备指令) */
async getPreferencesList() { async getPreferencesList() {
try { try {
const { rows } = await preferencesList({ serialNumber: this.device.serialNumber }); const { rows } = await preferencesList({
serialNumber: this.device.serialNumber,
productId: this.device.productId
});
this.quickParsing = rows; this.quickParsing = rows;
} catch (err) { } catch (err) {
console.log('🚀 ~ getPreferencesList ~ err:', err); console.log('🚀 ~ getPreferencesList ~ err:', err);
@ -1045,10 +1066,21 @@ $right-btn-color: #1890ff;
color: $right-btn-color; color: $right-btn-color;
cursor: pointer; cursor: pointer;
border-radius: 4px; border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 8px;
box-sizing: border-box;
&:first-child { &:first-child {
margin-top: 12px; margin-top: 12px;
} }
&.product-command {
border-color: #67c23a;
color: #67c23a;
background-color: rgba(103, 194, 58, 0.05);
}
} }
.right-bottom { .right-bottom {