From e33489898704f58c30cdba7159e5d44849fe0ef3 Mon Sep 17 00:00:00 2001 From: iteaj Date: Sat, 18 Jun 2022 22:38:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Edtu=E8=B0=83=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootstrap/pom.xml | 2 +- .../msn/core/controller/RoleController.java | 2 +- .../iboot/msn/iot/IotAutoConfiguration.java | 8 +- .../iot/controller/DeviceChildController.java | 69 ++++++++++++++ .../iteaj/iboot/msn/iot/entity/Device.java | 13 ++- .../iboot/msn/iot/entity/DeviceChild.java | 52 +++++++++++ .../msn/iot/mapper/DeviceChildMapper.java | 16 ++++ .../msn/iot/mapper/xml/DeviceChildMapper.xml | 15 +++ .../iboot/msn/iot/mapper/xml/DeviceMapper.xml | 1 + .../msn/iot/service/IDeviceChildService.java | 16 ++++ .../iboot/msn/iot/service/IDeviceService.java | 8 ++ .../service/impl/DeviceChildServiceImpl.java | 20 ++++ .../iot/service/impl/DeviceServiceImpl.java | 30 ++++++ .../iboot/msn/iot/websocket/DebugModel.java | 17 ++++ .../msn/iot/websocket/DtuDebugModel.java | 8 ++ .../msn/iot/websocket/IotDebugListener.java | 93 +++++++++++++++++++ .../src/main/resources/application-iot.yml | 2 + .../framework/result/OptionalResult.java | 33 +++---- 18 files changed, 383 insertions(+), 22 deletions(-) create mode 100644 bootstrap/src/main/java/com/iteaj/iboot/msn/iot/controller/DeviceChildController.java create mode 100644 bootstrap/src/main/java/com/iteaj/iboot/msn/iot/entity/DeviceChild.java create mode 100644 bootstrap/src/main/java/com/iteaj/iboot/msn/iot/mapper/DeviceChildMapper.java create mode 100644 bootstrap/src/main/java/com/iteaj/iboot/msn/iot/mapper/xml/DeviceChildMapper.xml create mode 100644 bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/IDeviceChildService.java create mode 100644 bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/impl/DeviceChildServiceImpl.java create mode 100644 bootstrap/src/main/java/com/iteaj/iboot/msn/iot/websocket/DebugModel.java create mode 100644 bootstrap/src/main/java/com/iteaj/iboot/msn/iot/websocket/DtuDebugModel.java create mode 100644 bootstrap/src/main/java/com/iteaj/iboot/msn/iot/websocket/IotDebugListener.java diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml index 45122ec2..6073fd2b 100644 --- a/bootstrap/pom.xml +++ b/bootstrap/pom.xml @@ -10,7 +10,7 @@ 4.0.0 bootstrap - 2.4.7 + 2.4.8 ${project.basedir} diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/core/controller/RoleController.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/core/controller/RoleController.java index 8158ee4b..bc47c21d 100644 --- a/bootstrap/src/main/java/com/iteaj/iboot/msn/core/controller/RoleController.java +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/core/controller/RoleController.java @@ -62,7 +62,7 @@ public class RoleController extends BaseController { */ @GetMapping("allMenus") public Result> allFunc() { - return this.menuService.selectMenuTrees(null); + return this.menuService.selectMenuTrees(new Menu()); } /** diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/IotAutoConfiguration.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/IotAutoConfiguration.java index 75f49926..eaf55f9d 100644 --- a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/IotAutoConfiguration.java +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/IotAutoConfiguration.java @@ -1,6 +1,9 @@ package com.iteaj.iboot.msn.iot; +import com.iteaj.iboot.msn.iot.websocket.IotDebugListener; +import org.apache.shiro.session.mgt.SessionManager; import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Profile; @@ -9,5 +12,8 @@ import org.springframework.context.annotation.Profile; @MapperScan({"com.iteaj.iboot.msn.iot.mapper"}) public class IotAutoConfiguration { - + @Bean + public IotDebugListener iotDebugListener(SessionManager sessionManager) { + return new IotDebugListener(sessionManager); + } } diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/controller/DeviceChildController.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/controller/DeviceChildController.java new file mode 100644 index 00000000..b9e1cd19 --- /dev/null +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/controller/DeviceChildController.java @@ -0,0 +1,69 @@ +package com.iteaj.iboot.msn.iot.controller; + +import java.util.List; +import com.iteaj.framework.result.Result; +import org.apache.shiro.authz.annotation.Logical; +import org.springframework.web.bind.annotation.*; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.iteaj.iboot.msn.iot.entity.DeviceChild; +import com.iteaj.iboot.msn.iot.service.IDeviceChildService; +import com.iteaj.framework.BaseController; + +/** + *

+ * 子设备管理 + *

+ * + * @author iteaj + * @since 2022-06-18 + */ +@RestController +@RequestMapping("/iot/deviceChild") +public class DeviceChildController extends BaseController { + + private final IDeviceChildService deviceChildService; + + public DeviceChildController(IDeviceChildService deviceChildService) { + this.deviceChildService = deviceChildService; + } + + /** + * 列表查询 + * @param page 分页 + * @param entity 搜索条件 + */ + @GetMapping("/view") + public Result> list(Page page, DeviceChild entity) { + return this.deviceChildService.page(page, entity); + } + + /** + * 获取编辑记录 + * @param id 记录id + */ + @GetMapping("/edit") + public Result getById(Long id) { + return this.deviceChildService.getById(id); + } + + /** + * 新增或者更新记录 + * @param entity + */ + @PostMapping("/saveOrUpdate") + public Result save(@RequestBody DeviceChild entity) { + return this.deviceChildService.saveOrUpdate(entity); + } + + /** + * 删除指定记录 + * @param idList + */ + @PostMapping("/del") + public Result remove(@RequestBody List idList) { + return this.deviceChildService.removeByIds(idList); + } +} + diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/entity/Device.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/entity/Device.java index d3a5d495..ded29663 100644 --- a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/entity/Device.java +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/entity/Device.java @@ -9,6 +9,9 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + /** *

* 设备表 @@ -30,9 +33,15 @@ public class Device extends BaseEntity { */ private String ip; + /** + * 设备uid + */ + private Long uid; + /** * 设备名称 */ + @NotBlank(message = "设备名称必填") private String name; /** @@ -58,6 +67,7 @@ public class Device extends BaseEntity { /** * 设备编号 */ + @NotBlank(message = "设备编号必填") private String deviceSn; private Date createTime; @@ -68,8 +78,9 @@ public class Device extends BaseEntity { private Date updateTime; /** - * 设备所属产品 + * 设备类型 */ + @NotNull(message = "设备类型必填") private Long deviceTypeId; diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/entity/DeviceChild.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/entity/DeviceChild.java new file mode 100644 index 00000000..ca4b4249 --- /dev/null +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/entity/DeviceChild.java @@ -0,0 +1,52 @@ +package com.iteaj.iboot.msn.iot.entity; + +import com.baomidou.mybatisplus.annotation.SqlCondition; +import com.baomidou.mybatisplus.annotation.TableField; +import com.iteaj.framework.BaseEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import java.util.Date; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * 子设备 + *

+ * + * @author iteaj + * @since 2022-06-18 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("iot_device_child") +public class DeviceChild extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 子设备名称 + */ + @TableField(condition = SqlCondition.LIKE) + private String name; + + /** + * 设备uid + */ + private Long uid; + + /** + * 子设备编号 + */ + private String childSn; + + /** + * 协议类型 + */ + private String protocolType; + + private Date createTime; + + +} diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/mapper/DeviceChildMapper.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/mapper/DeviceChildMapper.java new file mode 100644 index 00000000..ad775e1f --- /dev/null +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/mapper/DeviceChildMapper.java @@ -0,0 +1,16 @@ +package com.iteaj.iboot.msn.iot.mapper; + +import com.iteaj.iboot.msn.iot.entity.DeviceChild; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 子设备 Mapper 接口 + *

+ * + * @author iteaj + * @since 2022-06-18 + */ +public interface DeviceChildMapper extends BaseMapper { + +} diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/mapper/xml/DeviceChildMapper.xml b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/mapper/xml/DeviceChildMapper.xml new file mode 100644 index 00000000..cd33e1ee --- /dev/null +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/mapper/xml/DeviceChildMapper.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/mapper/xml/DeviceMapper.xml b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/mapper/xml/DeviceMapper.xml index 97cfb367..cf20a578 100644 --- a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/mapper/xml/DeviceMapper.xml +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/mapper/xml/DeviceMapper.xml @@ -6,6 +6,7 @@ + diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/IDeviceChildService.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/IDeviceChildService.java new file mode 100644 index 00000000..dcd26e59 --- /dev/null +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/IDeviceChildService.java @@ -0,0 +1,16 @@ +package com.iteaj.iboot.msn.iot.service; + +import com.iteaj.iboot.msn.iot.entity.DeviceChild; +import com.iteaj.framework.IBaseService; + +/** + *

+ * 子设备 服务类 + *

+ * + * @author iteaj + * @since 2022-06-18 + */ +public interface IDeviceChildService extends IBaseService { + +} diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/IDeviceService.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/IDeviceService.java index 1c1bcfc6..3b9782b0 100644 --- a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/IDeviceService.java +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/IDeviceService.java @@ -2,6 +2,7 @@ package com.iteaj.iboot.msn.iot.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.iteaj.framework.result.DetailResult; import com.iteaj.framework.result.Result; import com.iteaj.iboot.msn.iot.consts.DeviceStatus; import com.iteaj.iboot.msn.iot.dto.DeviceDto; @@ -32,4 +33,11 @@ public interface IDeviceService extends IBaseService { * @param status */ void update(String deviceSn, DeviceStatus status); + + /** + * 获取指定设备编号的记录 + * @param deviceSn + * @return + */ + DetailResult getByDeviceSn(String deviceSn); } diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/impl/DeviceChildServiceImpl.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/impl/DeviceChildServiceImpl.java new file mode 100644 index 00000000..9fd62ec7 --- /dev/null +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/impl/DeviceChildServiceImpl.java @@ -0,0 +1,20 @@ +package com.iteaj.iboot.msn.iot.service.impl; + +import com.iteaj.iboot.msn.iot.entity.DeviceChild; +import com.iteaj.iboot.msn.iot.mapper.DeviceChildMapper; +import com.iteaj.iboot.msn.iot.service.IDeviceChildService; +import com.iteaj.framework.BaseServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 子设备 服务实现类 + *

+ * + * @author iteaj + * @since 2022-06-18 + */ +@Service +public class DeviceChildServiceImpl extends BaseServiceImpl implements IDeviceChildService { + +} diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/impl/DeviceServiceImpl.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/impl/DeviceServiceImpl.java index a77f187f..36c28a23 100644 --- a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/impl/DeviceServiceImpl.java +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/service/impl/DeviceServiceImpl.java @@ -1,8 +1,11 @@ package com.iteaj.iboot.msn.iot.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.iteaj.framework.result.BooleanResult; +import com.iteaj.framework.result.DetailResult; import com.iteaj.framework.result.PageResult; import com.iteaj.framework.result.Result; import com.iteaj.iboot.msn.iot.consts.DeviceStatus; @@ -29,10 +32,37 @@ public class DeviceServiceImpl extends BaseServiceImpl imp return new PageResult<>(getBaseMapper().pageOfDetail(page, entity)); } + @Override + public BooleanResult save(Device entity) { + Device device = this.getByDeviceSn(entity.getDeviceSn()).getData(); + if(device != null) { + return new BooleanResult(false).fail("设备编号已经存在["+entity.getDeviceSn()+"]"); + } + + entity.setUid(IdWorker.getId()); + return super.save(entity); + } + + @Override + public BooleanResult updateById(Device entity) { + Device device = this.getOne(Wrappers.lambdaQuery() + .eq(Device::getDeviceSn, entity.getDeviceSn()) + .ne(Device::getId, entity.getId())).getData(); + if(device != null) { + return new BooleanResult(false).fail("设备编号已经存在["+entity.getDeviceSn()+"]"); + } + return super.updateById(entity); + } + @Override public void update(String deviceSn, DeviceStatus status) { update(Wrappers.lambdaUpdate() .set(Device::getStatus, status) .eq(Device::getDeviceSn, deviceSn)); } + + @Override + public DetailResult getByDeviceSn(String deviceSn) { + return getOne(Wrappers.lambdaQuery().eq(Device::getDeviceSn, deviceSn)); + } } diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/websocket/DebugModel.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/websocket/DebugModel.java new file mode 100644 index 00000000..f5d27a7b --- /dev/null +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/websocket/DebugModel.java @@ -0,0 +1,17 @@ +package com.iteaj.iboot.msn.iot.websocket; + +import lombok.Data; + +@Data +public class DebugModel { + + /** + * 设备编号 + */ + private String deviceSn; + + /** + * 客户端Sn + */ + private String clientSn; +} diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/websocket/DtuDebugModel.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/websocket/DtuDebugModel.java new file mode 100644 index 00000000..28f1c5d7 --- /dev/null +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/websocket/DtuDebugModel.java @@ -0,0 +1,8 @@ +package com.iteaj.iboot.msn.iot.websocket; + +import lombok.Data; + +@Data +public class DtuDebugModel extends DebugModel{ + +} diff --git a/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/websocket/IotDebugListener.java b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/websocket/IotDebugListener.java new file mode 100644 index 00000000..f0e40dee --- /dev/null +++ b/bootstrap/src/main/java/com/iteaj/iboot/msn/iot/websocket/IotDebugListener.java @@ -0,0 +1,93 @@ +package com.iteaj.iboot.msn.iot.websocket; + +import com.iteaj.iot.CoreConst; +import com.iteaj.iot.Message; +import com.iteaj.iot.server.websocket.WebSocketServerListener; +import com.iteaj.iot.server.websocket.impl.DefaultWebSocketServerComponent; +import com.iteaj.iot.server.websocket.impl.DefaultWebSocketServerProtocol; +import com.iteaj.iot.websocket.HttpRequestWrapper; +import com.iteaj.iot.websocket.WebSocketFilter; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.util.Attribute; +import org.apache.shiro.session.mgt.DefaultSessionKey; +import org.apache.shiro.session.mgt.SessionManager; + +import java.util.Arrays; + +public class IotDebugListener implements WebSocketServerListener, WebSocketFilter { + + private final SessionManager securityManager; + + public IotDebugListener(SessionManager securityManager) { + this.securityManager = securityManager; + } + + @Override + public String uri() { + return "/iot/debug"; + } + + @Override + public void onText(DefaultWebSocketServerProtocol protocol) { + String s = protocol.readText(); + protocol.response("accept"); + } + + @Override + public void onClose(DefaultWebSocketServerProtocol protocol) { + + } + + @Override + public void onBinary(DefaultWebSocketServerProtocol protocol) { + + } + + /** + * websocket 鉴权 + * @param request + * @return + */ + @Override + public HttpResponseStatus authentication(HttpRequest request) { + String sessionId = this.getSessionId(request); + if(sessionId != null) { + try { + securityManager.getSession(new DefaultSessionKey(sessionId)); + return HttpResponseStatus.OK; + } catch (Exception e) { + return HttpResponseStatus.UNAUTHORIZED; + } + } + + return HttpResponseStatus.UNAUTHORIZED; + } + + /** + * 注册设备编号 + * @param head + * @param equipCode + * @param channel + * @param component + * @return + */ + @Override + public Message.MessageHead register(Message.MessageHead head, String equipCode, Channel channel, DefaultWebSocketServerComponent component) { + if(equipCode == null) { + Attribute request = channel.attr(CoreConst.WEBSOCKET_REQ); + String sessionId = this.getSessionId(request.get().getRequest()); + head.setEquipCode(sessionId); // 使用sessionId作为设备编号 + } + return head; + } + + protected String getSessionId(HttpRequest request) { + String cookie = request.headers().get("Cookie"); + return Arrays.stream(cookie.split(";")) + .map(item -> item.split("=")) + .filter(item -> "JSESSIONID".equalsIgnoreCase(item[0].trim())) + .findFirst().orElse(new String[]{null, null})[1]; + } +} diff --git a/bootstrap/src/main/resources/application-iot.yml b/bootstrap/src/main/resources/application-iot.yml index 5871d6f8..df3edcd5 100644 --- a/bootstrap/src/main/resources/application-iot.yml +++ b/bootstrap/src/main/resources/application-iot.yml @@ -7,6 +7,8 @@ iot: server: proxy: start: false + websocket: + start: true mqtt: default: host: broker-cn.emqx.io diff --git a/framework/src/main/java/com/iteaj/framework/result/OptionalResult.java b/framework/src/main/java/com/iteaj/framework/result/OptionalResult.java index 4f124069..394ae6d4 100644 --- a/framework/src/main/java/com/iteaj/framework/result/OptionalResult.java +++ b/framework/src/main/java/com/iteaj/framework/result/OptionalResult.java @@ -1,9 +1,6 @@ package com.iteaj.framework.result; -import com.iteaj.framework.exception.ServiceException; - import java.util.Optional; -import java.util.function.Function; /** * create time: 2019/7/26 @@ -32,27 +29,27 @@ public abstract class OptionalResult> extends return Optional.ofNullable(this.getData()); } - /** - * @see Function#apply(Object) 直接返回响应的结果 - * @param function - * @return - */ - public _this build(Function function) { - if(null == function) throw new ServiceException("参数错误"); - - Result apply = function.apply(getData()); - return this.build(apply); + public _this ok() { + return this.ok(DMSG); } - public _this build(Result result) { - this.setCode(result.getCode()); - this.setMessage(result.getMessage()); + public _this ok(String msg) { + this.setCode(DCODE); + this.setMessage(msg); return (_this) this; } - public _this build(long code, String message) { + public _this fail() { + return this.fail(HttpResult.DEFAULT_ERROR_CODE, HttpResult.DEFAULT_ERROR_MSG); + } + + public _this fail(String msg) { + return this.fail(HttpResult.DEFAULT_ERROR_CODE, msg); + } + + public _this fail(long code, String msg) { this.setCode(code); - this.setMessage(message); + this.setMessage(msg); return (_this) this; }