feat(iot): 新增设备类型字段和分组管理功能

- 在 iot_things_model 表添加 dev_type 设备类型字段
- 修改 model_name 字段字符集并更新注释
- 新增设备类型字典数据和翻译配置
- 创建 iot_group 设备分组表并初始化基础数据
- 在 iot_category 表添加 industry_code 设备编码字段
- 更新 ThingsModel 实体类添加 devType 属性
- 修改 Excel 导入功能支持 sheetName 参数并优化类型识别逻辑
- 更新数据库映射文件支持设备类型字段操作
- 优化缓存实现按设备类型区分标识符避免冲突
- 调整导入数据验证逻辑并完善错误处理机制

Signed-off-by: Gjm <你的邮箱>
This commit is contained in:
Gjm
2026-04-09 16:38:57 +08:00
parent 7c07066408
commit a65b23cdad
8 changed files with 240 additions and 21 deletions

View File

@@ -16,13 +16,18 @@ import iot.lidee.iot.model.modbus.ModbusAndThingsVO;
import iot.lidee.iot.service.IThingsModelService; import iot.lidee.iot.service.IThingsModelService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.util.List; import java.util.List;
/** /**
@@ -167,11 +172,81 @@ public class ThingsModelController extends BaseController
@PostMapping(value = "/importData") @PostMapping(value = "/importData")
public AjaxResult importData(MultipartFile file,Long productId) throws Exception{ public AjaxResult importData(MultipartFile file,Long productId) throws Exception{
ExcelUtil<ThingsModel> excelUtil = new ExcelUtil<>(ThingsModel.class); ExcelUtil<ThingsModel> excelUtil = new ExcelUtil<>(ThingsModel.class);
List<ThingsModel> list = excelUtil.importExcel(file.getInputStream()); byte[] bytes = file.getBytes();
String result = thingsModelService.importData(list, productId);
Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(bytes));
Sheet sheet = wb.getSheetAt(0);
List<ThingsModel> list = excelUtil.importExcel(new ByteArrayInputStream(bytes));
if (!CollectionUtils.isEmpty( list)){
this.parseList(list);
}
String result = thingsModelService.importData(list, productId,sheet.getSheetName());
return AjaxResult.success(result); return AjaxResult.success(result);
} }
private void parseList(List<ThingsModel> list) {
if (list == null || list.isEmpty()) {
return;
}
for (ThingsModel thingsModel : list) {
String modelName = thingsModel.getModelName();
if (StringUtils.isEmpty(modelName)) {
thingsModel.setType(1);
continue;
}
thingsModel.setType(classifyModelType(modelName));
}
}
/**
* 根据物模型名称分类类型
* @param modelName 物模型名称
* @return 1-属性, 2-功能, 3-事件
*/
private Integer classifyModelType(String modelName) {
// 事件类型关键词
if (containsAny(modelName, "报警", "异常", "故障", "不能", "联锁", "过长", "超限", "超限度")) {
return 3;
}
// 特殊处理:包含"高"或"低"但不包含其他功能关键词的归为事件
if ((modelName.contains("") || modelName.contains(""))
&& !containsAny(modelName, "", "电机", "开门", "关门", "启动", "停止")) {
return 3;
}
if (containsAny(modelName, "", "电机", "开门", "关门", "启动", "停止", "复位", "引入",
"加压", "冷却", "排水", "抽气", "充气")) {
return 2;
}
// 默认为属性类型
return 1;
}
/**
* 判断字符串是否包含任意一个关键词
* @param str 待检查的字符串
* @param keywords 关键词数组
* @return 是否包含任一关键词
*/
private boolean containsAny(String str, String... keywords) {
if (str == null || keywords == null) {
return false;
}
for (String keyword : keywords) {
if (str.contains(keyword)) {
return true;
}
}
return false;
}
/** /**
* 获取modbus配置可选择物模型 * 获取modbus配置可选择物模型

View File

@@ -269,7 +269,8 @@ public class TSLCacheImpl implements ITSLCache {
} }
} }
//List -> MAP //List -> MAP
Map<String, String> thingsModelMap = thingsModels.stream().collect(Collectors.toMap(ThingsModel::getIdentifier, Map<String, String> thingsModelMap = thingsModels.stream().collect(Collectors.toMap(
thingsModel -> thingsModel.getIdentifier() + "_" + (thingsModel.getDevType() != null ? thingsModel.getDevType() : 0),
thingsModel -> { thingsModel -> {
//转换数据,减少不必要数据 //转换数据,减少不必要数据
ThingsModelValueItem dto = new ThingsModelValueItem(); ThingsModelValueItem dto = new ThingsModelValueItem();
@@ -281,9 +282,11 @@ public class TSLCacheImpl implements ITSLCache {
.setName_en_US(thingsModel.getModelName_en_US()) .setName_en_US(thingsModel.getModelName_en_US())
.setOrder(thingsModel.getModelOrder()) .setOrder(thingsModel.getModelOrder())
.setModelId(thingsModel.getModelId()) .setModelId(thingsModel.getModelId())
.setConfig(thingsModel.getModbusConfig()); .setConfig(thingsModel.getModbusConfig())
.setDevType(thingsModel.getDevType());
return JSONObject.toJSONString(dto); return JSONObject.toJSONString(dto);
})); },
(existingValue, newValue) -> existingValue));
/*缓存到redis*/ /*缓存到redis*/
String cacheKey = RedisKeyBuilder.buildTSLCacheKey(productId); String cacheKey = RedisKeyBuilder.buildTSLCacheKey(productId);

View File

@@ -30,7 +30,7 @@ public class ThingsModel extends BaseEntity
/** 物模型名称 */ /** 物模型名称 */
@ApiModelProperty("物模型名称") @ApiModelProperty("物模型名称")
@Excel(name = "物模型名称" ,prompt = "必填") @Excel(name = "Description" ,prompt = "必填")
private String modelName; private String modelName;
@@ -60,7 +60,7 @@ public class ThingsModel extends BaseEntity
/** 标识符,产品下唯一 */ /** 标识符,产品下唯一 */
@ApiModelProperty("标识符,产品下唯一") @ApiModelProperty("标识符,产品下唯一")
@Excel(name = "标识符",prompt = "modbus不填默认为寄存器地址") @Excel(name = "MeasuringPointName",prompt = "modbus不填默认为寄存器地址")
private String identifier; private String identifier;
/** 模型类别1-属性2-功能3-事件) */ /** 模型类别1-属性2-功能3-事件) */
@@ -111,7 +111,7 @@ public class ThingsModel extends BaseEntity
/** 数据类型integer、decimal、string、bool、array、enum */ /** 数据类型integer、decimal、string、bool、array、enum */
@ApiModelProperty(value = "数据类型", notes = "integer、decimal、string、bool、array、enum") @ApiModelProperty(value = "数据类型", notes = "integer、decimal、string、bool、array、enum")
@Excel(name = "数据类型", prompt = "integer、decimal、string、bool、array、enum") @Excel(name = "DataType", prompt = "integer、decimal、string、bool、array、enum")
private String datatype; private String datatype;
@Excel(name = "有效值范围") @Excel(name = "有效值范围")
@@ -131,5 +131,7 @@ public class ThingsModel extends BaseEntity
private String language; private String language;
private List<String> modelIdList; private List<String> modelIdList;
/** 设备类型 */
private Integer devType;
} }

View File

@@ -106,4 +106,6 @@ public class ThingsModelValueItem {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date ts; private Date ts;
private Integer devType;
} }

View File

@@ -108,7 +108,7 @@ public interface IThingsModelService
* @param tempSlaveId 从机编码 * @param tempSlaveId 从机编码
* @return 结果 * @return 结果
*/ */
public String importData(List<ThingsModel> lists,Long productId); public String importData(List<ThingsModel> lists,Long productId,String sheetName);
/** /**
* 根据产品id删除 产品物模型以及物模型缓存 * 根据产品id删除 产品物模型以及物模型缓存

View File

@@ -4,6 +4,7 @@ import java.util.*;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import iot.lidee.common.core.domain.entity.SysDictData;
import iot.lidee.common.core.domain.entity.SysUser; import iot.lidee.common.core.domain.entity.SysUser;
import iot.lidee.common.core.redis.RedisCache; import iot.lidee.common.core.redis.RedisCache;
import iot.lidee.common.core.redis.RedisKeyBuilder; import iot.lidee.common.core.redis.RedisKeyBuilder;
@@ -29,6 +30,7 @@ import iot.lidee.iot.model.modbus.ModbusAndThingsVO;
import iot.lidee.iot.model.varTemp.EnumClass; import iot.lidee.iot.model.varTemp.EnumClass;
import iot.lidee.iot.service.IThingsModelService; import iot.lidee.iot.service.IThingsModelService;
import iot.lidee.iot.cache.ITSLValueCache; import iot.lidee.iot.cache.ITSLValueCache;
import iot.lidee.system.mapper.SysDictDataMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -69,6 +71,8 @@ public class ThingsModelServiceImpl implements IThingsModelService {
private ITSLValueCache thingModelCache; private ITSLValueCache thingModelCache;
@Resource @Resource
private ITSLCache itslCache; private ITSLCache itslCache;
@Resource
private SysDictDataMapper sysDictDataMapper;
/** /**
@@ -130,6 +134,7 @@ public class ThingsModelServiceImpl implements IThingsModelService {
ThingsModel input = new ThingsModel(); ThingsModel input = new ThingsModel();
input.setProductId(thingsModel.getProductId()); input.setProductId(thingsModel.getProductId());
input.setLanguage(SecurityUtils.getLanguage()); input.setLanguage(SecurityUtils.getLanguage());
input.setDevType(thingsModel.getDevType());
List<ThingsModel> list = thingsModelMapper.selectThingsModelList(input); List<ThingsModel> list = thingsModelMapper.selectThingsModelList(input);
Boolean isRepeat = list.stream().anyMatch(x -> x.getIdentifier().equals(thingsModel.getIdentifier())); Boolean isRepeat = list.stream().anyMatch(x -> x.getIdentifier().equals(thingsModel.getIdentifier()));
if (!isRepeat) { if (!isRepeat) {
@@ -258,6 +263,7 @@ public class ThingsModelServiceImpl implements IThingsModelService {
ThingsModel input = new ThingsModel(); ThingsModel input = new ThingsModel();
input.setProductId(thingsModel.getProductId()); input.setProductId(thingsModel.getProductId());
input.setLanguage(SecurityUtils.getLanguage()); input.setLanguage(SecurityUtils.getLanguage());
input.setDatatype(thingsModel.getDatatype());
List<ThingsModel> list = thingsModelMapper.selectThingsModelList(input); List<ThingsModel> list = thingsModelMapper.selectThingsModelList(input);
Boolean isRepeat = list.stream().anyMatch(x -> x.getIdentifier().equals(thingsModel.getIdentifier()) && x.getModelId().longValue() != thingsModel.getModelId()); Boolean isRepeat = list.stream().anyMatch(x -> x.getIdentifier().equals(thingsModel.getIdentifier()) && x.getModelId().longValue() != thingsModel.getModelId());
if (!isRepeat) { if (!isRepeat) {
@@ -359,7 +365,7 @@ public class ThingsModelServiceImpl implements IThingsModelService {
* @param lists 数据列表 * @param lists 数据列表
* @return 结果 * @return 结果
*/ */
public String importData(List<ThingsModel> lists, Long productId) { public String importData(List<ThingsModel> lists, Long productId,String sheetName) {
if (null == productId || CollectionUtils.isEmpty(lists)) { if (null == productId || CollectionUtils.isEmpty(lists)) {
throw new ServiceException("导入数据异常"); throw new ServiceException("导入数据异常");
} }
@@ -369,13 +375,33 @@ public class ThingsModelServiceImpl implements IThingsModelService {
StringBuilder failSb = new StringBuilder(); StringBuilder failSb = new StringBuilder();
boolean result = false; boolean result = false;
Product product = productMapper.selectProductByProductId(productId); Product product = productMapper.selectProductByProductId(productId);
SysDictData sysDictData = new SysDictData();
sysDictData.setDictType("model_dev_type");
List<SysDictData> dictData = sysDictDataMapper.selectDictDataList(sysDictData);
Integer sheetNo = null;
if (dictData != null && StringUtils.isNotEmpty(sheetName)) {
for (SysDictData data : dictData) {
String dictLabel = data.getDictLabel();
log.info("对比字典项 - Label: [{}], Value: [{}]", dictLabel, data.getDictValue());
if (StringUtils.isNotEmpty(dictLabel) && dictLabel.trim().equals(sheetName.trim())) {
sheetNo = Integer.valueOf(data.getDictValue());
log.info("匹配成功! sheetNo = {}", sheetNo);
break;
}
}
}
if (sheetNo == null) {
log.warn("未找到Sheet名称 [{}] 对应的字典配置sheetNo将为null", sheetName);
}
for (ThingsModel model : lists) { for (ThingsModel model : lists) {
try { try {
model.setProductId(product.getProductId()); model.setProductId(product.getProductId());
model.setProductName(product.getProductName()); model.setProductName(product.getProductName());
//处理数据定义 //处理数据定义
this.parseSpecs(model); this.parseSpecs(model);
result = this.importData(model); result = this.importData(model,sheetNo);
success++; success++;
succSb.append("<br/>").append(success).append(",采集点: ").append(model.getModelName()); succSb.append("<br/>").append(success).append(",采集点: ").append(model.getModelName());
} catch (Exception e) { } catch (Exception e) {
@@ -384,12 +410,12 @@ public class ThingsModelServiceImpl implements IThingsModelService {
failSb.append("<br/>").append(failure).append(",采集点: ").append(model.getModelName()).append("导入失败"); failSb.append("<br/>").append(failure).append(",采集点: ").append(model.getModelName()).append("导入失败");
} }
} }
if (result) { // if (result) {
log.error("标识符不能重复"); // log.error("标识符不能重复");
failure++; // failure++;
failSb.append("<br/>").append(failure).append(",采集点: ").append("标识符不能重复"); // failSb.append("<br/>").append(failure).append(",采集点: ").append("标识符不能重复");
throw new ServiceException(failSb.toString()); // throw new ServiceException(failSb.toString());
} // }
if (failure > 0) { if (failure > 0) {
throw new ServiceException(failSb.toString()); throw new ServiceException(failSb.toString());
} }
@@ -404,10 +430,11 @@ public class ThingsModelServiceImpl implements IThingsModelService {
/** /**
* 导入单个物模型 * 导入单个物模型
*/ */
private boolean importData(ThingsModel thingsModel){ private boolean importData(ThingsModel thingsModel,Integer sheetNo){
ThingsModel input=new ThingsModel(); ThingsModel input=new ThingsModel();
input.setProductId(thingsModel.getProductId()); input.setProductId(thingsModel.getProductId());
input.setLanguage(SecurityUtils.getLanguage()); input.setLanguage(SecurityUtils.getLanguage());
input.setDevType(sheetNo);
List<ThingsModel> list = thingsModelMapper.selectThingsModelList(input); List<ThingsModel> list = thingsModelMapper.selectThingsModelList(input);
Boolean isRepeat = list.stream().anyMatch(x -> x.getIdentifier().equals(thingsModel.getIdentifier())); Boolean isRepeat = list.stream().anyMatch(x -> x.getIdentifier().equals(thingsModel.getIdentifier()));
if (!isRepeat) { if (!isRepeat) {
@@ -419,6 +446,7 @@ public class ThingsModelServiceImpl implements IThingsModelService {
thingsModel.setTenantId(user.getUserId()); thingsModel.setTenantId(user.getUserId());
thingsModel.setTenantName(user.getUserName()); thingsModel.setTenantName(user.getUserName());
} }
thingsModel.setDevType(sheetNo);
thingsModel.setCreateTime(DateUtils.getNowDate()); thingsModel.setCreateTime(DateUtils.getNowDate());
thingsModelMapper.insertThingsModel(thingsModel); thingsModelMapper.insertThingsModel(thingsModel);
return false; return false;

View File

@@ -30,6 +30,7 @@
<result property="remark" column="remark"/> <result property="remark" column="remark"/>
<result property="isReadonly" column="is_readonly"/> <result property="isReadonly" column="is_readonly"/>
<result property="modelOrder" column="model_order"/> <result property="modelOrder" column="model_order"/>
<result property="devType" column="dev_type"/>
</resultMap> </resultMap>
<resultMap type="iot.lidee.iot.model.ThingsModelPerm" id="ThingsModelPermResult"> <resultMap type="iot.lidee.iot.model.ThingsModelPerm" id="ThingsModelPermResult">
@@ -70,7 +71,8 @@
update_time, update_time,
remark, remark,
is_readonly, is_readonly,
model_order model_order,
dev_type
from iot_things_model from iot_things_model
</sql> </sql>
@@ -84,13 +86,16 @@
m.model_name as model_name_zh_cn, t.en_us as model_name_en_us, m.model_name as model_name_zh_cn, t.en_us as model_name_en_us,
m.product_id, m.product_name, m.tenant_id, m.tenant_name, m.identifier, m.type, m.datatype, m.formula, m.product_id, m.product_name, m.tenant_id, m.tenant_name, m.identifier, m.type, m.datatype, m.formula,
m.specs, m.is_chart, m.is_share_perm, m.is_history, m.is_monitor, m.is_app, m.del_flag, m.create_by, m.specs, m.is_chart, m.is_share_perm, m.is_history, m.is_monitor, m.is_app, m.del_flag, m.create_by,
m.create_time, m.update_by, m.update_time, m.remark, m.is_readonly, m.model_order m.create_time, m.update_by, m.update_time, m.remark, m.is_readonly, m.model_order,m.dev_type
from iot_things_model m from iot_things_model m
left join iot_things_model_translate t on m.model_id = t.id left join iot_things_model_translate t on m.model_id = t.id
<where> <where>
<if test="productId != null"> <if test="productId != null">
and m.product_id = #{productId} and m.product_id = #{productId}
</if> </if>
<if test="modelName != null and modelName != ''">
and model_name like concat('%',#{modelName},'%')
</if>
<if test="type!=null"> <if test="type!=null">
and type = #{type} and type = #{type}
</if> </if>
@@ -106,6 +111,9 @@
<if test="isReadonly != null "> <if test="isReadonly != null ">
and is_readonly = #{isReadonly} and is_readonly = #{isReadonly}
</if> </if>
<if test="devType != null ">
and dev_type = #{devType}
</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=")">
@@ -157,7 +165,7 @@
end as model_name, end as model_name,
m.product_id, m.product_name, m.tenant_id, m.tenant_name, m.identifier, m.type, m.datatype, m.formula, m.product_id, m.product_name, m.tenant_id, m.tenant_name, m.identifier, m.type, m.datatype, m.formula,
m.specs, m.is_chart, m.is_share_perm, m.is_history, m.is_monitor, m.is_app, m.del_flag, m.create_by, m.specs, m.is_chart, m.is_share_perm, m.is_history, m.is_monitor, m.is_app, m.del_flag, m.create_by,
m.create_time, m.update_by, m.update_time, m.remark, m.is_readonly, m.model_order m.create_time, m.update_by, m.update_time, m.remark, m.is_readonly, m.model_order,m.dev_type
from iot_things_model m from iot_things_model m
left join iot_things_model_translate t on m.model_id = t.id left join iot_things_model_translate t on m.model_id = t.id
where model_id = #{modelId} where model_id = #{modelId}
@@ -258,6 +266,9 @@
<if test="modelOrder != null"> <if test="modelOrder != null">
model_order, model_order,
</if> </if>
<if test="devType != null">
dev_type,
</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="modelName != null and modelName != ''"> <if test="modelName != null and modelName != ''">
@@ -329,6 +340,9 @@
<if test="modelOrder != null"> <if test="modelOrder != null">
#{modelOrder}, #{modelOrder},
</if> </if>
<if test="devType != null">
#{devType},
</if>
</trim> </trim>
</insert> </insert>
@@ -438,6 +452,9 @@
<if test="modelOrder != null"> <if test="modelOrder != null">
model_order = #{modelOrder}, model_order = #{modelOrder},
</if> </if>
<if test="devType != null">
dev_type = #{devType},
</if>
</trim> </trim>
where model_id = #{modelId} where model_id = #{modelId}
</update> </update>

92
sql/2026-04-08.sql Normal file
View File

@@ -0,0 +1,92 @@
ALTER TABLE `iot_things_model`
ADD COLUMN `dev_type` int NULL COMMENT '设备类型' AFTER `is_app`;
ALTER TABLE `iot_things_model`
MODIFY COLUMN `model_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '物模型名称' AFTER `model_id`;
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (753, '灭菌柜', 'Sterilizer');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (752, '铝盖机', 'Aluminum Capping Machine');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (751, '冻干机', 'Lyophilizer');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (750, '灌装机', 'Filling Machine');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (749, '胶塞机', 'Stoppering Machine');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (748, '进料系统', 'Feeding System');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (747, '出料系统', 'Sterilizer & Discharging System');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (746, '轧盖机', 'Sealing Machine');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (745, 'AGV', 'Automated Guided Vehicle');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (744, '灯检机', 'Light Inspection Machine');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (743, '裹包机', 'Wrapping Machine');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (742, '烘箱机', 'Drying Oven');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (741, '空调', 'HVAC');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (740, '配液', 'Solution Preparation');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (739, '贴标机', 'Labeling Machine');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (738, '灌封机', 'Filling and Sealing Machine');
INSERT INTO `sys_dict_data_translate` (`id`, `zh_cn`, `en_us`) VALUES (737, '洗瓶机', 'Bottle Washing Machine');
INSERT INTO `sys_dict_type` (`dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES ('模型设备类型', 'model_dev_type', '0', 'admin', '2026-04-08 17:09:50', '', NULL, '模型设备类型');
INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (753, 0, '灭菌柜', '17', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:11:52', 'admin', '2026-04-09 08:47:13', NULL);
INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (752, 0, '铝盖机', '16', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:11:52', 'admin', '2026-04-09 08:47:13', NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '15', '冻干机', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:15:31', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '14', '灌装机', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:15:16', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '13', '胶塞机', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:15:04', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '12', '进料系统', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:14:52', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '11', '出料系统', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:14:38', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '10', '轧盖机', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:14:16', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '9', 'AGV', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:14:05', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '8', '灯验机', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:13:45', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '7', '裹包机', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:13:32', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '6', '烘箱机', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:13:08', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '5', '空调', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:12:56', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '4', '配液', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:12:48', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '3', '贴标机', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:12:36', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '2', '灌封机', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:12:09', '', NULL, NULL);
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (0, '1', '洗瓶机', 'model_dev_type', NULL, 'default', 'N', '0', 'admin', '2026-04-08 17:11:52', 'admin', '2026-04-08 17:12:21', NULL);
ALTER TABLE `iot_category`
ADD COLUMN `industry_code` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '设备编码' AFTER `remark`;
DROP TABLE IF EXISTS `iot_group`;
CREATE TABLE `iot_group` (
`group_id` bigint NOT NULL AUTO_INCREMENT COMMENT '分组ID',
`group_name` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '分组名称',
`group_order` tinyint NOT NULL DEFAULT 0 COMMENT '分组排序',
`user_id` bigint NULL DEFAULT NULL COMMENT '用户ID',
`user_name` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '用户昵称',
`del_flag` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '0' COMMENT '删除标志0代表存在 2代表删除',
`create_by` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '备注',
`parent_id` bigint NULL DEFAULT NULL COMMENT '父级ID',
`industry_code` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '设备编码',
PRIMARY KEY (`group_id`) USING BTREE,
INDEX `iot_group_index_user_id`(`user_id` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 28 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '设备分组' ROW_FORMAT = DYNAMIC;
INSERT INTO `iot_group` VALUES (1, '生产线', 1, 1, 'admin', '0', '', '2026-03-31 10:30:26', '', '2026-03-31 10:30:29', NULL, NULL, 'SCX');
INSERT INTO `iot_group` VALUES (9, '一般粉针生产线', 0, 1, 'admin', '0', '', '2026-03-31 10:31:39', '', '2026-03-31 11:52:37', NULL, 1, 'YBFZ');
INSERT INTO `iot_group` VALUES (10, '冻干粉针1号生产线', 1, 1, 'admin', '0', '', '2026-03-31 11:11:50', '', '2026-03-31 11:55:29', NULL, 1, 'DGFZ001');
INSERT INTO `iot_group` VALUES (11, '动力车间', 4, 1, 'admin', '0', '', '2026-03-31 11:18:34', '', '2026-03-31 11:55:45', NULL, 1, 'DLCJ');
INSERT INTO `iot_group` VALUES (12, '冻干粉针2号生产线', 2, 1, 'admin', '0', '', '2026-03-31 11:53:50', '', '2026-03-31 11:55:32', NULL, 1, 'DGFZ002');
INSERT INTO `iot_group` VALUES (13, '冻干粉针3号生产线', 3, 1, 'admin', '0', '', '2026-03-31 11:54:59', '', '2026-03-31 11:55:36', NULL, 1, 'DGFZ003');
INSERT INTO `iot_group` VALUES (14, '化验室', 5, 1, 'admin', '0', '', '2026-03-31 11:55:57', '', NULL, NULL, 1, 'HYS');
INSERT INTO `iot_group` VALUES (15, '原料车间1号生产线', 6, 1, 'admin', '0', '', '2026-03-31 11:56:17', '', NULL, NULL, 1, 'YLCJ001');
INSERT INTO `iot_group` VALUES (16, '原料车间2号生产线', 7, 1, 'admin', '0', '', '2026-03-31 11:56:34', '', '2026-03-31 11:56:44', '', 1, 'YLCJ002');
INSERT INTO `iot_group` VALUES (17, '原料车间3号生产线', 8, 1, 'admin', '0', '', '2026-03-31 11:57:01', '', NULL, NULL, 1, 'YLCJ003');
INSERT INTO `iot_group` VALUES (18, '口服固体制剂1号生产线', 9, 1, 'admin', '0', '', '2026-03-31 11:57:14', '', NULL, NULL, 1, 'KFGT001');
INSERT INTO `iot_group` VALUES (19, '口服固体制剂2号生产线', 10, 1, 'admin', '0', '', '2026-03-31 11:57:33', '', NULL, NULL, 1, 'KFGT002');
INSERT INTO `iot_group` VALUES (20, '头孢粉针生产线', 11, 1, 'admin', '0', '', '2026-03-31 11:57:44', '', NULL, NULL, 1, 'TBFZ');
INSERT INTO `iot_group` VALUES (21, '小容量注射剂1号生产线', 12, 1, 'admin', '0', '', '2026-03-31 11:57:57', '', NULL, NULL, 1, 'XRLZSJ001');
INSERT INTO `iot_group` VALUES (22, '小容量注射剂2号生产线', 13, 1, 'admin', '0', '', '2026-03-31 11:58:11', '', NULL, NULL, 1, 'XRLZSJ002');
INSERT INTO `iot_group` VALUES (23, '技术中心', 15, 1, 'admin', '0', '', '2026-03-31 13:20:38', '', NULL, NULL, 1, 'JSZX');
INSERT INTO `iot_group` VALUES (24, '储运部', 16, 1, 'admin', '0', '', '2026-03-31 13:21:13', '', NULL, NULL, 1, 'CYB');
INSERT INTO `iot_group` VALUES (25, '其他', 17, 1, 'admin', '0', '', '2026-03-31 13:21:48', '', NULL, NULL, 1, 'QT');
SET FOREIGN_KEY_CHECKS = 1;