提交
This commit is contained in:
parent
51a74d15be
commit
439526cba2
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2025 Tz
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package me.zhengjie.modules.security.config;
|
||||||
|
|
||||||
|
|
||||||
|
public class WebSocketConfig {
|
||||||
|
|
||||||
|
public static final String PING = "ping";
|
||||||
|
public static final String PONG = "pong";
|
||||||
|
public static final String TOPIC_PREFIX = "sdcp";
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package me.zhengjie.modules.security.config.enums;
|
||||||
|
|
||||||
|
|
||||||
|
public enum CapabilitieEnum {
|
||||||
|
|
||||||
|
FILE_TRANSFER, // 支持文件传输
|
||||||
|
PRINT_CONTROL, // 支持打印控制
|
||||||
|
VIDEO_STREAM; // 支持视频流传输
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2025 Tz
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package me.zhengjie.modules.security.config.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PreviousStatus与CurrentStatus定义
|
||||||
|
*/
|
||||||
|
public enum CurrentStatusEnum {
|
||||||
|
|
||||||
|
SDCP_MACHINE_STATUS_DEFAULT(-1, "默认/断开"),
|
||||||
|
SDCP_MACHINE_STATUS_IDLE(0, "空闲"),
|
||||||
|
SDCP_MACHINE_STATUS_PRINTING(1, "执行打印任务中"),
|
||||||
|
SDCP_MACHINE_STATUS_PREPARE(2, "打印准备过程中"), //
|
||||||
|
SDCP_MACHINE_STATUS_SPADE(3, "铲件过程中"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private Integer code;
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
public Integer getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(Integer code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentStatusEnum(Integer code, String text) {
|
||||||
|
this.code = code;
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CurrentStatusEnum getEnumByNum(int value) {
|
||||||
|
for (CurrentStatusEnum os : CurrentStatusEnum.values()) {
|
||||||
|
if (value == os.getCode()) {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2025 Tz
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package me.zhengjie.modules.security.config.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ErrorStatusEnum
|
||||||
|
*/
|
||||||
|
public enum ErrorStatusEnum {
|
||||||
|
|
||||||
|
SDCP_PRINT_ERROR_DEFAULT(-1, "默认"),
|
||||||
|
SDCP_PRINT_ERROR_NONE(0 ,"正常"),
|
||||||
|
SDCP_PRINT_ERROR_CHECKFILE(1 ,"文件校验失败"),
|
||||||
|
SDCP_PRINT_ERROR_DEVICE(2 ,"设备或加密出错"),
|
||||||
|
SDCP_PRINT_ERROR_PREPARE(3 ,"打印准备过程出错"),
|
||||||
|
SDCP_PRINT_ERROR_PRINT(4 ,"打印出错"),
|
||||||
|
SDCP_PRINT_ERROR_LIQUID(5 ,"加液失败"),
|
||||||
|
SDCP_PRINT_ERROR_SPADE(6 ,"铲件失败"),
|
||||||
|
SDCP_PRINT_ERROR_PIC(7 ,"图片异物"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private Integer code;
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
public Integer getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(Integer code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorStatusEnum(Integer code, String text) {
|
||||||
|
this.code = code;
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ErrorStatusEnum getEnumByNum(int value) {
|
||||||
|
for (ErrorStatusEnum os : ErrorStatusEnum.values()) {
|
||||||
|
if (value == os.getCode()) {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package me.zhengjie.modules.security.config.enums;
|
||||||
|
|
||||||
|
|
||||||
|
public enum MethodEnum {
|
||||||
|
|
||||||
|
request,
|
||||||
|
response,
|
||||||
|
status,
|
||||||
|
attributes,
|
||||||
|
error,
|
||||||
|
notice;
|
||||||
|
|
||||||
|
}
|
@ -15,15 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package me.zhengjie.modules.security.config.enums;
|
package me.zhengjie.modules.security.config.enums;
|
||||||
|
|
||||||
/**
|
public enum MsgEnum {
|
||||||
* @author ZhangHouYing
|
|
||||||
* @date 2019-08-10 9:56
|
|
||||||
*/
|
|
||||||
public enum MsgType {
|
|
||||||
/** 连接 */
|
/** 连接 */
|
||||||
CONNECT,
|
CONNECT,
|
||||||
/** 关闭 */
|
/** 关闭 */
|
||||||
CLOSE,
|
CLOSE,
|
||||||
|
/** 断开连接 */
|
||||||
|
DISCONNECT,
|
||||||
/** 信息 */
|
/** 信息 */
|
||||||
INFO,
|
INFO,
|
||||||
/** 错误 */
|
/** 错误 */
|
@ -0,0 +1,57 @@
|
|||||||
|
package me.zhengjie.modules.security.config.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PrintInfo 状态
|
||||||
|
*/
|
||||||
|
public enum PrintInfoStatusEnum {
|
||||||
|
|
||||||
|
SDCP_PRINT_STATUS_DEFAULT(-1, "默认"),
|
||||||
|
SDCP_PRINT_STATUS_IDLE(0, "空闲"),
|
||||||
|
SDCP_PRINT_STATUS_HOMING(1,"归零中"),
|
||||||
|
SDCP_PRINT_STATUS_DROPPING(2,"下降中"),
|
||||||
|
SDCP_PRINT_STATUS_EXPOSURING(3,"曝光中"),
|
||||||
|
SDCP_PRINT_STATUS_LIFTING(4,"抬升中"),
|
||||||
|
SDCP_PRINT_STATUS_PAUSING(5,"正在执行暂停动作中"),
|
||||||
|
SDCP_PRINT_STATUS_PAUSED(6,"已暂停"),
|
||||||
|
SDCP_PRINT_STATUS_STOPPING(7,"正在执行停止动作中"),
|
||||||
|
SDCP_PRINT_STATUS_STOPED(8,"已停止"),
|
||||||
|
SDCP_PRINT_STATUS_COMPLETE(9,"打印完成"),
|
||||||
|
SDCP_PRINT_STATUS_FILE_CHECKING(10, "文件检测中"),
|
||||||
|
SDCP_PRINT_STATUS_LIQUID(11, "加液中"),
|
||||||
|
SDCP_PRINT_STATUS_SPADE(12, "铲件中"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private Integer code;
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
PrintInfoStatusEnum(Integer code, String text) {
|
||||||
|
this.code = code;
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(Integer code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PrintInfoStatusEnum getEnumByNum(int value) {
|
||||||
|
for (PrintInfoStatusEnum os : PrintInfoStatusEnum.values()) {
|
||||||
|
if (value == os.getCode()) {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -24,6 +24,7 @@ import java.sql.Timestamp;
|
|||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
@ -44,6 +45,9 @@ public class BusDevice implements Serializable {
|
|||||||
@ApiModelProperty(value = "设备唯一标识")
|
@ApiModelProperty(value = "设备唯一标识")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "机器序号")
|
||||||
|
private String deviceCode;
|
||||||
|
|
||||||
@ApiModelProperty(value = "设备序列号(唯一)")
|
@ApiModelProperty(value = "设备序列号(唯一)")
|
||||||
private String deviceSn;
|
private String deviceSn;
|
||||||
|
|
||||||
@ -53,28 +57,31 @@ public class BusDevice implements Serializable {
|
|||||||
@ApiModelProperty(value = "品牌")
|
@ApiModelProperty(value = "品牌")
|
||||||
private String brand;
|
private String brand;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "设备名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
@ApiModelProperty(value = "固件版本")
|
@ApiModelProperty(value = "固件版本")
|
||||||
private String firmwareVersion;
|
private String firmwareVersion;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "协议版本")
|
||||||
|
private String protocolVersion;
|
||||||
|
|
||||||
@ApiModelProperty(value = "放置位置")
|
@ApiModelProperty(value = "放置位置")
|
||||||
private String location;
|
private String location;
|
||||||
|
|
||||||
@ApiModelProperty(value = "设备状态(1=在线,2=离线,3=故障)")
|
@ApiModelProperty(value = "设备状态(-1=默认/断开,0=空闲,1=任务中,2=准备中,3=铲件中)")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
@ApiModelProperty(value = "最近上线时间")
|
@ApiModelProperty(value = "打印状态(-1默认,0空闲,1归零中,2下降中,3曝光中,4抬升中,5正在执行暂停动作中,6已暂停,7正在执行停止动作中,8已停止,9打印完成,10文件检测中,11加液中,12铲件中)")
|
||||||
private Timestamp onlineTime;
|
private Integer printStatus;
|
||||||
|
|
||||||
@ApiModelProperty(value = "最近下线时间")
|
@ApiModelProperty(value = "异常状态(-1默认,0正常,1文件校验失败,2设备或加密错误,3打印准备过程出错,4打印出错,5加液失败,6铲件失败,7图片异物)")
|
||||||
private Timestamp offlineTime;
|
private Integer errorStatus;
|
||||||
|
|
||||||
@ApiModelProperty(value = "累计时长(分钟)")
|
|
||||||
private Integer totalPrintTime;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "备注")
|
@ApiModelProperty(value = "备注")
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
@ApiModelProperty(value = "类型:1打印机,2摄像头")
|
@ApiModelProperty(value = "类型:1打印机")
|
||||||
private Integer type;
|
private Integer type;
|
||||||
|
|
||||||
@ApiModelProperty(value = "创建者")
|
@ApiModelProperty(value = "创建者")
|
||||||
@ -89,6 +96,9 @@ public class BusDevice implements Serializable {
|
|||||||
@ApiModelProperty(value = "更新时间")
|
@ApiModelProperty(value = "更新时间")
|
||||||
private Timestamp updateTime;
|
private Timestamp updateTime;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private List<BusDeviceCommand> commandList;
|
||||||
|
|
||||||
public void copy(BusDevice source){
|
public void copy(BusDevice source){
|
||||||
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
|
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
|
||||||
}
|
}
|
||||||
|
@ -47,14 +47,14 @@ public class BusDeviceCommand implements Serializable {
|
|||||||
@ApiModelProperty(value = "指令名称")
|
@ApiModelProperty(value = "指令名称")
|
||||||
private String commandName;
|
private String commandName;
|
||||||
|
|
||||||
@ApiModelProperty(value = "指令类型(1=控制,2=查询,3=校准)")
|
@ApiModelProperty(value = "指令类型(FILE_TRANSFER=文件传输,PRINT_CONTROL=打印控制,VIDEO_STREAM=视频)")
|
||||||
private Integer commandType;
|
private String commandType;
|
||||||
|
|
||||||
@ApiModelProperty(value = "指令描述")
|
@ApiModelProperty(value = "指令描述")
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
@ApiModelProperty(value = "是否为系统指令(1=是,2=否)")
|
@ApiModelProperty(value = "状态:1有效,0无效")
|
||||||
private Integer isSystem;
|
private Integer status;
|
||||||
|
|
||||||
@ApiModelProperty(value = "指令参数(JSON格式)")
|
@ApiModelProperty(value = "指令参数(JSON格式)")
|
||||||
private String commandParams;
|
private String commandParams;
|
||||||
|
@ -39,33 +39,21 @@ public class BusUserDevice implements Serializable {
|
|||||||
@ApiModelProperty(value = "绑定记录唯一标识")
|
@ApiModelProperty(value = "绑定记录唯一标识")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@ApiModelProperty(value = "用户ID(外键)")
|
@ApiModelProperty(value = "用户ID(外键)")
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@ApiModelProperty(value = "设备ID(外键)")
|
@ApiModelProperty(value = "设备ID(外键)")
|
||||||
private Long deviceId;
|
private Long deviceId;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@ApiModelProperty(value = "是否为主用户(1=是,2=否)")
|
|
||||||
private Integer isPrimary;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@ApiModelProperty(value = "绑定状态(1=有效,2=失效)")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "创建者")
|
@ApiModelProperty(value = "创建者")
|
||||||
private String createBy;
|
private String createBy;
|
||||||
|
|
||||||
@ApiModelProperty(value = "更新者")
|
@ApiModelProperty(value = "更新者")
|
||||||
private String updateBy;
|
private String updateBy;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@ApiModelProperty(value = "创建时间")
|
@ApiModelProperty(value = "创建时间")
|
||||||
private Timestamp createTime;
|
private Timestamp createTime;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@ApiModelProperty(value = "更新时间")
|
@ApiModelProperty(value = "更新时间")
|
||||||
private Timestamp updateTime;
|
private Timestamp updateTime;
|
||||||
|
|
||||||
|
@ -38,4 +38,7 @@ public interface BusDeviceMapper extends BaseMapper<BusDevice> {
|
|||||||
List<BusDevice> findAll(@Param("criteria") BusDeviceQueryCriteria criteria);
|
List<BusDevice> findAll(@Param("criteria") BusDeviceQueryCriteria criteria);
|
||||||
|
|
||||||
List<BusTreeVo> getDevice();
|
List<BusTreeVo> getDevice();
|
||||||
|
|
||||||
|
void updateDeviceStatus(@Param("deviceSn") String deviceSn, @Param("status") Integer status, @Param("printStatus") Integer printStatus, @Param("errorStatus") Integer errorStatus, @Param("remark") String remark);
|
||||||
|
|
||||||
}
|
}
|
@ -18,6 +18,9 @@ package me.zhengjie.modules.system.service;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import me.zhengjie.modules.security.config.enums.CurrentStatusEnum;
|
||||||
|
import me.zhengjie.modules.security.config.enums.ErrorStatusEnum;
|
||||||
|
import me.zhengjie.modules.security.config.enums.PrintInfoStatusEnum;
|
||||||
import me.zhengjie.modules.system.domain.BusDevice;
|
import me.zhengjie.modules.system.domain.BusDevice;
|
||||||
import me.zhengjie.modules.system.domain.Menu;
|
import me.zhengjie.modules.system.domain.Menu;
|
||||||
import me.zhengjie.modules.system.domain.dto.BusDeviceQueryCriteria;
|
import me.zhengjie.modules.system.domain.dto.BusDeviceQueryCriteria;
|
||||||
@ -31,6 +34,13 @@ import me.zhengjie.utils.PageResult;
|
|||||||
**/
|
**/
|
||||||
public interface BusDeviceService extends IService<BusDevice> {
|
public interface BusDeviceService extends IService<BusDevice> {
|
||||||
|
|
||||||
|
List<BusDevice> getByDeviceSns(List<String> deviceSns);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改设备状态
|
||||||
|
*/
|
||||||
|
void updateDeviceStatus(String deviceSn, CurrentStatusEnum e1, PrintInfoStatusEnum e2, ErrorStatusEnum e3, String remarks);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询数据分页
|
* 查询数据分页
|
||||||
* @param criteria 条件
|
* @param criteria 条件
|
||||||
@ -70,4 +80,6 @@ public interface BusDeviceService extends IService<BusDevice> {
|
|||||||
|
|
||||||
List<BusTreeVo> getDeviceTree(Long pid);
|
List<BusTreeVo> getDeviceTree(Long pid);
|
||||||
|
|
||||||
|
void updateOrAdd(BusDevice entity);
|
||||||
|
|
||||||
}
|
}
|
@ -15,10 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package me.zhengjie.modules.system.service.impl;
|
package me.zhengjie.modules.system.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import me.zhengjie.exception.BadRequestException;
|
import me.zhengjie.exception.BadRequestException;
|
||||||
import me.zhengjie.modules.front.service.WeChatService;
|
import me.zhengjie.modules.front.service.WeChatService;
|
||||||
|
import me.zhengjie.modules.security.config.enums.CurrentStatusEnum;
|
||||||
|
import me.zhengjie.modules.security.config.enums.ErrorStatusEnum;
|
||||||
|
import me.zhengjie.modules.security.config.enums.PrintInfoStatusEnum;
|
||||||
import me.zhengjie.modules.system.domain.BusDevice;
|
import me.zhengjie.modules.system.domain.BusDevice;
|
||||||
import me.zhengjie.modules.system.domain.Menu;
|
import me.zhengjie.modules.system.domain.BusDeviceCommand;
|
||||||
import me.zhengjie.modules.system.domain.dto.BusDeviceQueryCriteria;
|
import me.zhengjie.modules.system.domain.dto.BusDeviceQueryCriteria;
|
||||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||||
import me.zhengjie.modules.system.mapper.BusCommandMapper;
|
import me.zhengjie.modules.system.mapper.BusCommandMapper;
|
||||||
@ -29,13 +33,17 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import me.zhengjie.utils.CacheKey;
|
import me.zhengjie.utils.CacheKey;
|
||||||
import me.zhengjie.utils.RedisUtils;
|
import me.zhengjie.utils.RedisUtils;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import me.zhengjie.utils.PageUtil;
|
import me.zhengjie.utils.PageUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import me.zhengjie.utils.PageResult;
|
import me.zhengjie.utils.PageResult;
|
||||||
|
|
||||||
@ -53,6 +61,45 @@ public class BusDeviceServiceImpl extends ServiceImpl<BusDeviceMapper, BusDevice
|
|||||||
private final WeChatService weChatService;
|
private final WeChatService weChatService;
|
||||||
private final RedisUtils redisUtils;
|
private final RedisUtils redisUtils;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BusDevice> getByDeviceSns(List<String> deviceSns) {
|
||||||
|
return busDeviceMapper.selectList(new LambdaQueryWrapper<BusDevice>().in(BusDevice::getDeviceSn, deviceSns));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Async
|
||||||
|
@Override
|
||||||
|
public void updateDeviceStatus(String deviceSn, CurrentStatusEnum e1, PrintInfoStatusEnum e2, ErrorStatusEnum e3, String remarks) {
|
||||||
|
busDeviceMapper.updateDeviceStatus(deviceSn, e1.getCode(), e2.getCode(), e3.getCode(), remarks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Async
|
||||||
|
@Override
|
||||||
|
public void updateOrAdd(BusDevice entity) {
|
||||||
|
List<BusDevice> devices = getByDeviceSns(new ArrayList<String>() {{ add(entity.getDeviceSn()); }});
|
||||||
|
if (devices.isEmpty()) {
|
||||||
|
busDeviceMapper.insert(entity);
|
||||||
|
}
|
||||||
|
List<BusDeviceCommand> newList = entity.getCommandList();
|
||||||
|
List<BusDeviceCommand> oldList = busCommandMapper.selectList(new LambdaQueryWrapper<BusDeviceCommand>().eq(BusDeviceCommand::getDeviceId, devices.get(0).getId()));
|
||||||
|
if (newList.isEmpty() && !oldList.isEmpty()) {
|
||||||
|
List<Long> dIds = oldList.stream().map(BusDeviceCommand::getId).collect(Collectors.toList());
|
||||||
|
busCommandMapper.deleteBatchIds(dIds);
|
||||||
|
} else if (!newList.isEmpty()) {
|
||||||
|
// 查询第一个列表中 CommandType 在第二个列表中不存在的元素
|
||||||
|
List<BusDeviceCommand> addList = newList.stream().filter(p1 -> oldList.stream().noneMatch(p2 -> Objects.equals(p1.getCommandType(), p2.getCommandType()))).collect(Collectors.toList());
|
||||||
|
for (BusDeviceCommand add : addList) {
|
||||||
|
add.setDeviceId(devices.get(0).getId());
|
||||||
|
busCommandMapper.insert(add);
|
||||||
|
}
|
||||||
|
// 查询第二个列表中 CommandType 在第一个列表中不存在的元素
|
||||||
|
List<BusDeviceCommand> updList = oldList.stream().filter(p2 -> newList.stream().noneMatch(p1 -> Objects.equals(p2.getCommandType(), p1.getCommandType()))).collect(Collectors.toList());
|
||||||
|
for (BusDeviceCommand upd : updList) {
|
||||||
|
upd.setStatus(0); // 修改成指令无效
|
||||||
|
busCommandMapper.updateById(upd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<BusDevice> queryAll(BusDeviceQueryCriteria criteria, Page<Object> page){
|
public PageResult<BusDevice> queryAll(BusDeviceQueryCriteria criteria, Page<Object> page){
|
||||||
return PageUtil.toPage(busDeviceMapper.findAll(criteria, page));
|
return PageUtil.toPage(busDeviceMapper.findAll(criteria, page));
|
||||||
|
@ -16,18 +16,14 @@
|
|||||||
package me.zhengjie.modules.system.service.webstocket;
|
package me.zhengjie.modules.system.service.webstocket;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import me.zhengjie.modules.security.config.enums.MsgType;
|
import me.zhengjie.modules.security.config.enums.MsgEnum;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ZhangHouYing
|
|
||||||
* @date 2019-08-10 9:55
|
|
||||||
*/
|
|
||||||
@Data
|
@Data
|
||||||
public class SocketMsg {
|
public class SocketMsg {
|
||||||
private String msg;
|
private String msg;
|
||||||
private MsgType msgType;
|
private MsgEnum msgType;
|
||||||
|
|
||||||
public SocketMsg(String msg, MsgType msgType) {
|
public SocketMsg(String msg, MsgEnum msgType) {
|
||||||
this.msg = msg;
|
this.msg = msg;
|
||||||
this.msgType = msgType;
|
this.msgType = msgType;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package me.zhengjie.modules.system.service.webstocket;
|
||||||
|
|
||||||
|
import jodd.util.StringUtil;
|
||||||
|
import lombok.Data;
|
||||||
|
import me.zhengjie.modules.security.config.enums.MethodEnum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制请求(小程序->主板): sdcp/request/${MainboardID}
|
||||||
|
* 控制响应(主板->小程序): sdcp/response/${MainboardID}
|
||||||
|
* 状态信息(主板->小程序):sdcp/status/${MainboardID}
|
||||||
|
* 属性信息(主板->小程序):sdcp/attributes/${MainboardID}
|
||||||
|
* 错误信息(主板->小程序):sdcp/error/${MainboardID}
|
||||||
|
* 通知信息(主板->小程序):sdcp/notice/${MainboardID}
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class WebSocketParam {
|
||||||
|
|
||||||
|
// 消息topic
|
||||||
|
private String Topic;
|
||||||
|
|
||||||
|
// 设备ID
|
||||||
|
private String MainboardID;
|
||||||
|
|
||||||
|
// 消息类型
|
||||||
|
private MethodEnum method;
|
||||||
|
|
||||||
|
public String getMainboardID() {
|
||||||
|
if (StringUtil.isBlank(MainboardID)) {
|
||||||
|
return getTopic().substring(getTopic().lastIndexOf("/") + 1);
|
||||||
|
}
|
||||||
|
return MainboardID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MethodEnum getMethod() {
|
||||||
|
for (MethodEnum os : MethodEnum.values()) {
|
||||||
|
if (getTopic().contains(os.name())) {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,143 +1,317 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019-2025 Tz
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package me.zhengjie.modules.system.service.webstocket;
|
package me.zhengjie.modules.system.service.webstocket;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import me.zhengjie.modules.security.config.WebSocketConfig;
|
||||||
|
import me.zhengjie.modules.security.config.enums.*;
|
||||||
|
import me.zhengjie.modules.system.domain.BusDevice;
|
||||||
|
import me.zhengjie.modules.system.domain.BusDeviceCommand;
|
||||||
|
import me.zhengjie.modules.system.domain.dto.BusDeviceQueryCriteria;
|
||||||
|
import me.zhengjie.modules.system.service.BusDeviceService;
|
||||||
|
import me.zhengjie.modules.system.service.webstocket.req.WebSocketReqDTO;
|
||||||
|
import me.zhengjie.modules.system.service.webstocket.req.WebSocketReqData;
|
||||||
|
import me.zhengjie.modules.system.service.webstocket.res.WebSocketResAttributes;
|
||||||
|
import me.zhengjie.modules.system.service.webstocket.res.WebSocketResDTO;
|
||||||
|
import me.zhengjie.modules.system.service.webstocket.res.WebSocketResPrintInfo;
|
||||||
|
import me.zhengjie.modules.system.service.webstocket.res.WebSocketResStatus;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
import javax.websocket.*;
|
import javax.websocket.*;
|
||||||
import javax.websocket.server.PathParam;
|
|
||||||
import javax.websocket.server.ServerEndpoint;
|
import javax.websocket.server.ServerEndpoint;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.net.URI;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
@ServerEndpoint("/sdcp/{method}/{mainboardId}")
|
@ServerEndpoint("/webSocket")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
|
@Order(2)
|
||||||
public class WebSocketServer {
|
public class WebSocketServer {
|
||||||
|
|
||||||
/**
|
@Autowired private BusDeviceService deviceService;
|
||||||
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
|
private static BusDeviceService myDeviceService;
|
||||||
*/
|
|
||||||
private static final CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
|
|
||||||
|
|
||||||
/**
|
// 存储设备
|
||||||
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
|
private static final CopyOnWriteArraySet<String> deviceList = new CopyOnWriteArraySet<>();
|
||||||
*/
|
// 存储连接的前端客户端
|
||||||
private Session session;
|
private static final ConcurrentHashMap<String, Session> vueClients = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/**
|
// 第三方WebSocket连接
|
||||||
* 接收sid
|
@Value("${thirdParty.socket.url}")
|
||||||
*/
|
private String thirdPartyWsUrl;
|
||||||
private String sid = "";
|
private static Session thirdPartySession;
|
||||||
|
private static WebSocketContainer thirdPartyContainer;
|
||||||
|
// 重连机制
|
||||||
|
private final ScheduledExecutorService reconnectExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
|
||||||
|
// 初始化连接第三方WebSocket
|
||||||
|
@PostConstruct
|
||||||
|
public void initThirdPartyWebSocket() {
|
||||||
|
if (null == thirdPartyContainer && null == thirdPartySession) { return; }
|
||||||
|
try {
|
||||||
|
thirdPartyContainer = ContainerProvider.getWebSocketContainer();
|
||||||
|
thirdPartySession = thirdPartyContainer.connectToServer(ThirdPartyClient.class, URI.create(thirdPartyWsUrl));
|
||||||
|
log.info("【客户端->第三方】连接成功");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.info("【客户端->第三方】连接失败,等待5秒重新连接");
|
||||||
|
scheduleReconnect();
|
||||||
|
}
|
||||||
|
if (null == myDeviceService) {
|
||||||
|
myDeviceService = deviceService;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安排重连任务
|
||||||
|
private void scheduleReconnect() {
|
||||||
|
reconnectExecutor.schedule(this::initThirdPartyWebSocket, 5, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 连接建立成功调用的方法
|
* 连接建立成功调用的方法
|
||||||
*/
|
*/
|
||||||
@OnOpen
|
@OnOpen
|
||||||
public void onOpen(Session session, @PathParam("method") String method, @PathParam("mainboardId") String mainboardId) {
|
public void onOpen(Session session) {
|
||||||
this.session = session;
|
log.info("【VUE->服务端】连接成功:sessionId={}", session.getId());
|
||||||
//如果存在就先删除一个,防止重复推送消息
|
vueClients.put(session.getId(), session);
|
||||||
webSocketSet.removeIf(webSocket -> webSocket.sid.equals(mainboardId));
|
|
||||||
webSocketSet.add(this);
|
|
||||||
this.sid = mainboardId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 连接关闭调用的方法
|
* 连接关闭调用的方法
|
||||||
*/
|
*/
|
||||||
@OnClose
|
@OnClose
|
||||||
public void onClose() {
|
public void onClose(Session session) {
|
||||||
webSocketSet.remove(this);
|
log.info("【VUE->服务端】连接断开:sessionId={}", session.getId());
|
||||||
|
vueClients.remove(session.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接异常时
|
||||||
|
* @param session
|
||||||
|
* @param error
|
||||||
|
*/
|
||||||
|
@OnError
|
||||||
|
public void onError(Session session, Throwable error) {
|
||||||
|
log.info("【VUE->服务端】发现异常:sessionId={}", session.getId());
|
||||||
|
error.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 收到客户端消息后调用的方法
|
* 收到客户端消息后调用的方法
|
||||||
*
|
|
||||||
* @param message 客户端发送过来的消息
|
* @param message 客户端发送过来的消息
|
||||||
*/
|
*/
|
||||||
@OnMessage
|
@OnMessage
|
||||||
public void onMessage(String message, Session session, @PathParam("method") String method, @PathParam("mainboardId") String mainboardId) {
|
public void onMessage(String message) {
|
||||||
log.info("收到来" + sid + "的信息:" + message);
|
log.info("WebSocketServer onMessage 收到消息={}", message);
|
||||||
if ("ping".equals(message)) {
|
sendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主推消息给客户端
|
||||||
|
*/
|
||||||
|
private void sendMessage(String message) {
|
||||||
|
// 根据类型,操作不同的消息
|
||||||
|
|
||||||
|
// todo 如果是指令,则转发给第三方WebSocket
|
||||||
|
if (!(thirdPartySession != null && thirdPartySession.isOpen())) {
|
||||||
|
log.info("指令发送失败,原因: websocket未连接");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sendMessage("pong");
|
thirdPartySession.getBasicRemote().sendText(message);
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
log.info("指令发送异常,原因:", e);
|
||||||
} else {
|
|
||||||
// 群发消息
|
|
||||||
for (WebSocketServer item : webSocketSet) {
|
|
||||||
try {
|
|
||||||
item.sendMessage(message);
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error(e.getMessage(), e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 处理来自第三方WebSocket的消息并转发给Vue前端
|
||||||
|
@ClientEndpoint
|
||||||
|
public static class ThirdPartyClient {
|
||||||
|
|
||||||
|
@OnOpen
|
||||||
|
public void onOpen(Session session) {
|
||||||
|
log.info("【第三方客户端】连接成功");
|
||||||
|
initDevices();
|
||||||
|
socketMsg(new SocketMsg("已连接", MsgEnum.CONNECT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnMessage
|
||||||
|
public void onMessage(String message, Session session) {
|
||||||
|
log.info("【第三方客户端】收到消息:{}", message);
|
||||||
|
messageReceiveHandle(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClose
|
||||||
|
public void onClose(Session session) {
|
||||||
|
log.info("【第三方客户端】连接断开");
|
||||||
|
socketMsg(new SocketMsg("连接断开", MsgEnum.DISCONNECT));
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnError
|
@OnError
|
||||||
public void onError(Session session, Throwable error) {
|
public void onError(Session session, Throwable error) {
|
||||||
log.error("发生错误", error);
|
log.info("【第三方客户端】发现异常,原因:", error);
|
||||||
|
socketMsg(new SocketMsg("连接异常", MsgEnum.ERROR));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// 收到消息,解析,做响应的处理
|
||||||
* 实现服务器主动推送
|
private void messageReceiveHandle(String message) {
|
||||||
*/
|
// 如果是 [心跳] 检测,忽略
|
||||||
private void sendMessage(String message) throws IOException {
|
if (WebSocketConfig.PONG.equals(message)) {
|
||||||
this.session.getBasicRemote().sendText(message);
|
log.info("<<< 心跳反馈,忽略");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 其余信息是第三方推送过来的消息 / 发送的指令
|
||||||
|
message = message.replace("\\", "");
|
||||||
|
WebSocketParam param = JSON.parseObject(message, WebSocketParam.class);
|
||||||
|
MethodEnum method = param.getMethod();
|
||||||
|
String deviceSn = param.getMainboardID();
|
||||||
|
log.info("<<< 方式 {}", method.name());
|
||||||
|
// 只关心我已有的设备
|
||||||
|
if (!deviceList.contains(deviceSn)) {
|
||||||
|
log.info("<<< 设备【{}】在系统未找到,忽略", deviceSn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// request 说明是vue要发送指令给第三方
|
||||||
|
if (method == MethodEnum.request) {
|
||||||
|
WebSocketReqDTO requestReq = JSON.parseObject(message, WebSocketReqDTO.class);
|
||||||
|
if (null == requestReq.getCommand()) {
|
||||||
|
log.info("<<< 命令类型未找到");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// todo 发送指令给第三方
|
||||||
|
CapabilitieEnum command = requestReq.getCommand();
|
||||||
|
// messageSendHandle(null);
|
||||||
|
}
|
||||||
|
// 其他,说明是第三方上推给我们客服端
|
||||||
|
else {
|
||||||
|
WebSocketResDTO resDTO = JSON.parseObject(message, WebSocketResDTO.class);
|
||||||
|
if (method == MethodEnum.response) {
|
||||||
|
// List<BusDevice> devices = new ArrayList<>();
|
||||||
|
// BusDevice device = new BusDevice();
|
||||||
|
// device.setId();
|
||||||
|
// devices.add(device);
|
||||||
|
// pushVueClients();
|
||||||
|
} else if (method == MethodEnum.status) {
|
||||||
|
WebSocketResStatus status = resDTO.getStatus();
|
||||||
|
WebSocketResPrintInfo printInfo = status.getPrintInfo();
|
||||||
|
myDeviceService.updateDeviceStatus(
|
||||||
|
deviceSn,
|
||||||
|
CurrentStatusEnum.getEnumByNum(status.getCurrentStatus()),
|
||||||
|
PrintInfoStatusEnum.getEnumByNum(printInfo.getStatus()),
|
||||||
|
ErrorStatusEnum.SDCP_PRINT_ERROR_NONE,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
BusDevice info = new BusDevice();
|
||||||
|
info.setDeviceSn(deviceSn);
|
||||||
|
info.setStatus(CurrentStatusEnum.getEnumByNum(status.getCurrentStatus()).getCode());
|
||||||
|
info.setPrintStatus(PrintInfoStatusEnum.getEnumByNum(printInfo.getStatus()).getCode());
|
||||||
|
info.setErrorStatus(ErrorStatusEnum.SDCP_PRINT_ERROR_NONE.getCode());
|
||||||
|
socketMsg(new SocketMsg(JSON.toJSONString(info), MsgEnum.INFO));
|
||||||
|
} else if (method == MethodEnum.attributes) {
|
||||||
|
WebSocketResAttributes attributes = resDTO.getAttributes();
|
||||||
|
String[] capabilities = attributes.getCapabilities();
|
||||||
|
BusDevice entity = new BusDevice();
|
||||||
|
entity.setDeviceSn(deviceSn);
|
||||||
|
entity.setName(attributes.getName());
|
||||||
|
entity.setModel(attributes.getMachineName());
|
||||||
|
entity.setFirmwareVersion(attributes.getFirmwareVersion());
|
||||||
|
entity.setProtocolVersion(attributes.getProtocolVersion());
|
||||||
|
List<BusDeviceCommand> commandList = new ArrayList<>();
|
||||||
|
for (String capability : capabilities) {
|
||||||
|
BusDeviceCommand command = new BusDeviceCommand();
|
||||||
|
command.setCommandType(capability);
|
||||||
|
commandList.add(command);
|
||||||
|
}
|
||||||
|
entity.setCommandList(commandList);
|
||||||
|
myDeviceService.updateOrAdd(entity);
|
||||||
|
} else if (method == MethodEnum.error) {
|
||||||
|
WebSocketResStatus status = resDTO.getStatus();
|
||||||
|
WebSocketResPrintInfo printInfo = status.getPrintInfo();
|
||||||
|
myDeviceService.updateDeviceStatus(
|
||||||
|
deviceSn,
|
||||||
|
CurrentStatusEnum.getEnumByNum(status.getCurrentStatus()),
|
||||||
|
PrintInfoStatusEnum.getEnumByNum(printInfo.getStatus()),
|
||||||
|
ErrorStatusEnum.SDCP_PRINT_ERROR_NONE,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
BusDevice info = new BusDevice();
|
||||||
|
info.setDeviceSn(deviceSn);
|
||||||
|
info.setStatus(CurrentStatusEnum.getEnumByNum(status.getCurrentStatus()).getCode());
|
||||||
|
info.setPrintStatus(PrintInfoStatusEnum.getEnumByNum(printInfo.getStatus()).getCode());
|
||||||
|
info.setErrorStatus(ErrorStatusEnum.SDCP_PRINT_ERROR_NONE.getCode());
|
||||||
|
socketMsg(new SocketMsg(JSON.toJSONString(info), MsgEnum.ERROR));
|
||||||
|
} else if (method == MethodEnum.notice) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void socketMsg(SocketMsg socketMsg) {
|
||||||
* 群发自定义消息
|
|
||||||
*/
|
|
||||||
public static void sendInfo(SocketMsg socketMsg, @PathParam("mainboardId") String mainboardId) throws IOException {
|
|
||||||
String message = JSON.toJSONString(socketMsg);
|
String message = JSON.toJSONString(socketMsg);
|
||||||
log.info("推送消息到" + mainboardId + ",推送内容:" + message);
|
pushVueClients(message);
|
||||||
for (WebSocketServer item : webSocketSet) {
|
}
|
||||||
|
|
||||||
|
// 将消息广播给所有前端客户端
|
||||||
|
private void pushVueClients(String message) {
|
||||||
|
vueClients.forEach((id, clientSession) -> {
|
||||||
try {
|
try {
|
||||||
//这里可以设定只推送给这个sid的,为null则全部推送
|
clientSession.getBasicRemote().sendText(message);
|
||||||
if (mainboardId == null) {
|
} catch (IOException e) {
|
||||||
item.sendMessage(message);
|
e.printStackTrace();
|
||||||
} else if (item.sid.equals(mainboardId)) {
|
|
||||||
item.sendMessage(message);
|
|
||||||
}
|
}
|
||||||
} catch (IOException ignored) {
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 发送消息给第三方
|
||||||
|
private void messageSendHandle(String message) {
|
||||||
|
if (!(thirdPartySession != null && thirdPartySession.isOpen())) {
|
||||||
|
log.info("<<< 发送消息给第三方-失败 原因: websocket 已关闭");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
log.info(">>> 发送消息给第三方 {}", message);
|
||||||
|
thirdPartySession.getBasicRemote().sendText(message);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.info("<<< 发送消息给第三方-异常 原因:", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public boolean equals(Object o) {
|
* 初始化设备,并向第三方发指令,为了拿到设备的状态
|
||||||
if (this == o) {
|
*/
|
||||||
return true;
|
private void initDevices() {
|
||||||
|
log.info(">>> 设备初始化");
|
||||||
|
List<BusDevice> devices = myDeviceService.queryAll(new BusDeviceQueryCriteria());
|
||||||
|
for (BusDevice device : devices) {
|
||||||
|
String deviceSn = device.getDeviceSn();
|
||||||
|
long currentTimeLong = System.currentTimeMillis();
|
||||||
|
WebSocketReqDTO reqDTO = new WebSocketReqDTO();
|
||||||
|
reqDTO.setTopic(WebSocketConfig.TOPIC_PREFIX + "/" + MethodEnum.request.name() + "/" + deviceSn);
|
||||||
|
WebSocketReqData data = new WebSocketReqData();
|
||||||
|
data.setCmd(0);
|
||||||
|
data.setData(new Object());
|
||||||
|
data.setRequestID(currentTimeLong + "");
|
||||||
|
data.setMainboardID(device.getDeviceSn());
|
||||||
|
data.setTimeStamp(currentTimeLong);
|
||||||
|
data.setFrom(0);
|
||||||
|
reqDTO.setData(data);
|
||||||
|
// 发送 状态刷新消息(Cmd:0) 指令
|
||||||
|
messageSendHandle(JSON.toJSONString(reqDTO));
|
||||||
|
// 订阅设备
|
||||||
|
deviceList.add(deviceSn);
|
||||||
|
}
|
||||||
|
log.info("<<< 设备初始化");
|
||||||
}
|
}
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
WebSocketServer that = (WebSocketServer) o;
|
|
||||||
return Objects.equals(session, that.session) &&
|
|
||||||
Objects.equals(sid, that.sid);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(session, sid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package me.zhengjie.modules.system.service.webstocket.req;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import me.zhengjie.modules.security.config.enums.CapabilitieEnum;
|
||||||
|
import me.zhengjie.modules.system.service.webstocket.WebSocketParam;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class WebSocketReqDTO extends WebSocketParam implements Serializable {
|
||||||
|
|
||||||
|
// 消息参数
|
||||||
|
private WebSocketReqData Data;
|
||||||
|
|
||||||
|
// 机器品牌标识,32位UUID
|
||||||
|
private String Id;
|
||||||
|
|
||||||
|
// 指令类型
|
||||||
|
private CapabilitieEnum command;
|
||||||
|
|
||||||
|
public CapabilitieEnum getCommand() {
|
||||||
|
for (CapabilitieEnum os : CapabilitieEnum.values()) {
|
||||||
|
if (getTopic().contains(os.name())) {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package me.zhengjie.modules.system.service.webstocket.req;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class WebSocketReqData implements Serializable {
|
||||||
|
|
||||||
|
// 请求命令
|
||||||
|
private Integer Cmd;
|
||||||
|
|
||||||
|
private Object Data;
|
||||||
|
|
||||||
|
// 请求ID
|
||||||
|
private String RequestID;
|
||||||
|
|
||||||
|
// 主板ID
|
||||||
|
private String MainboardID;
|
||||||
|
|
||||||
|
// 时间戳
|
||||||
|
private Long TimeStamp;
|
||||||
|
|
||||||
|
// 标识命令来源
|
||||||
|
private Integer From;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package me.zhengjie.modules.system.service.webstocket.res;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "Name": "4KL200URH300.4K", // 机器名称
|
||||||
|
* "MachineName": "3DPLUS", // 机型名称
|
||||||
|
* "MainboardID": "12345678", // 主板ID 设备编号, 唯一识别码
|
||||||
|
* "ProtocolVersion": "V3.0.0", // 协议版本(暂留
|
||||||
|
* "FirmwareVersion": "V1.0.0" // 固件版本(暂留
|
||||||
|
* "NumberOfVideoStreamConnected": 1, // 已连接视频流
|
||||||
|
* "MaximumVideoStreamAllowed": 1, // 最多可连接的视频流
|
||||||
|
* "Capabilities":[
|
||||||
|
* "FILE_TRANSFER", // 支持文件传输
|
||||||
|
* "PRINT_CONTROL", // 支持打印控制
|
||||||
|
* "VIDEO_STREAM" // 支持视频流传输
|
||||||
|
* ], // 主板端支持的子协议
|
||||||
|
* "CameraStatus": 0, // 摄像头接入状态 0断开, 1连接
|
||||||
|
* "RemainingMemory": 123455, // 剩余的文件存储空间大小(bit)
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class WebSocketResAttributes implements Serializable {
|
||||||
|
|
||||||
|
// 机器名称
|
||||||
|
private String Name;
|
||||||
|
// 机型名称
|
||||||
|
private String MachineName;
|
||||||
|
// 主板ID 设备编号, 唯一识别码
|
||||||
|
private String MainboardID;
|
||||||
|
// 协议版本(暂留
|
||||||
|
private String ProtocolVersion;
|
||||||
|
// 固件版本(暂留
|
||||||
|
private String FirmwareVersion;
|
||||||
|
// 已连接视频流
|
||||||
|
private Integer NumberOfVideoStreamConnected;
|
||||||
|
// 最多可连接的视频流
|
||||||
|
private Integer MaximumVideoStreamAllowed;
|
||||||
|
// 主板端支持的子协议
|
||||||
|
private String[] Capabilities;
|
||||||
|
// FILE_TRANSFER 支持文件传输
|
||||||
|
// PRINT_CONTROL 支持打印控制
|
||||||
|
// VIDEO_STREAM 支持视频流传输
|
||||||
|
|
||||||
|
// 摄像头接入状态 0断开, 1连接
|
||||||
|
private Integer CameraStatus;
|
||||||
|
// 剩余的文件存储空间大小(bit)
|
||||||
|
private Integer RemainingMemory;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package me.zhengjie.modules.system.service.webstocket.res;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import me.zhengjie.modules.system.service.webstocket.WebSocketParam;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class WebSocketResDTO extends WebSocketParam implements Serializable {
|
||||||
|
|
||||||
|
// 消息参数
|
||||||
|
private WebSocketResData Data;
|
||||||
|
|
||||||
|
// 状态
|
||||||
|
private WebSocketResStatus Status;
|
||||||
|
|
||||||
|
// 属性
|
||||||
|
private WebSocketResAttributes Attributes;
|
||||||
|
|
||||||
|
// 机器品牌标识,32位UUID
|
||||||
|
private String Id;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package me.zhengjie.modules.system.service.webstocket.res;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class WebSocketResData implements Serializable {
|
||||||
|
|
||||||
|
// 请求命令
|
||||||
|
private Integer Cmd;
|
||||||
|
|
||||||
|
private Object Data;
|
||||||
|
|
||||||
|
// 请求ID
|
||||||
|
private String RequestID;
|
||||||
|
|
||||||
|
// 时间戳
|
||||||
|
private Long TimeStamp;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package me.zhengjie.modules.system.service.webstocket.res;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class WebSocketResPrintInfo implements Serializable {
|
||||||
|
|
||||||
|
// 打印子状态
|
||||||
|
private Integer Status;
|
||||||
|
// 当前打印层数
|
||||||
|
private Integer CurrentLayer;
|
||||||
|
// 打印任务总层数
|
||||||
|
private Integer TotalLayer;
|
||||||
|
// 当前已打印时间(ms)
|
||||||
|
private Integer CurrentTicks;
|
||||||
|
// 总打印时间(ms)
|
||||||
|
private Integer TotalTicks;
|
||||||
|
// 打印文件名称
|
||||||
|
private String Filename;
|
||||||
|
// 错误码,参考后文 ErrorEnum
|
||||||
|
private Integer ErrorNumber;
|
||||||
|
// 当前任务数量
|
||||||
|
private Integer Task;
|
||||||
|
// 总共任务数量
|
||||||
|
private Integer Total;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package me.zhengjie.modules.system.service.webstocket.res;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class WebSocketResStatus implements Serializable {
|
||||||
|
|
||||||
|
// 当前机器状态,部分状态可以共存
|
||||||
|
private Integer CurrentStatus;
|
||||||
|
|
||||||
|
// 上一次机器状态
|
||||||
|
private Integer PreviousStatus;
|
||||||
|
|
||||||
|
// 当前温度(℃) float
|
||||||
|
private Integer Temp;
|
||||||
|
|
||||||
|
// 箱体目标温度(℃) float
|
||||||
|
private Integer humidity;
|
||||||
|
|
||||||
|
private WebSocketResPrintInfo PrintInfo;
|
||||||
|
|
||||||
|
}
|
@ -108,15 +108,17 @@ weChat:
|
|||||||
secret: 1b5eca11a1058361b0f14c5933ef6bd6
|
secret: 1b5eca11a1058361b0f14c5933ef6bd6
|
||||||
|
|
||||||
# socket
|
# socket
|
||||||
ws:
|
thirdParty:
|
||||||
|
socket:
|
||||||
url: ws://127.0.0.1:8000/webSocket
|
url: ws://127.0.0.1:8000/webSocket
|
||||||
server:
|
|
||||||
# 客户端心跳开关
|
# server:
|
||||||
clientSwitch: false
|
# # 客户端心跳开关
|
||||||
# 间隔时间 单位:秒
|
# clientSwitch: false
|
||||||
interval: 10
|
# # 间隔时间 单位:秒
|
||||||
# 最大错误次数
|
# interval: 10
|
||||||
maxMissCount: 10
|
# # 最大错误次数
|
||||||
|
# maxMissCount: 10
|
||||||
|
|
||||||
# 文件存储路径
|
# 文件存储路径
|
||||||
file:
|
file:
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<result column="command_name" property="commandName"/>
|
<result column="command_name" property="commandName"/>
|
||||||
<result column="command_type" property="commandType"/>
|
<result column="command_type" property="commandType"/>
|
||||||
<result column="description" property="description"/>
|
<result column="description" property="description"/>
|
||||||
<result column="is_system" property="isSystem"/>
|
<result column="status" property="status"/>
|
||||||
<result column="command_params" property="commandParams"/>
|
<result column="command_params" property="commandParams"/>
|
||||||
<result column="create_by" property="createBy"/>
|
<result column="create_by" property="createBy"/>
|
||||||
<result column="update_by" property="updateBy"/>
|
<result column="update_by" property="updateBy"/>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, device_id, command_name, command_type, description, is_system, command_params, create_by, update_by, create_time, update_time
|
id, device_id, command_name, command_type, description, status, command_params, create_by, update_by, create_time, update_time
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="findAll" resultMap="BaseResultMap">
|
<select id="findAll" resultMap="BaseResultMap">
|
||||||
|
@ -3,15 +3,17 @@
|
|||||||
<mapper namespace="me.zhengjie.modules.system.mapper.BusDeviceMapper">
|
<mapper namespace="me.zhengjie.modules.system.mapper.BusDeviceMapper">
|
||||||
<resultMap id="BaseResultMap" type="me.zhengjie.modules.system.domain.BusDevice">
|
<resultMap id="BaseResultMap" type="me.zhengjie.modules.system.domain.BusDevice">
|
||||||
<id column="id" property="id"/>
|
<id column="id" property="id"/>
|
||||||
|
<result column="device_code" property="deviceCode"/>
|
||||||
<result column="device_sn" property="deviceSn"/>
|
<result column="device_sn" property="deviceSn"/>
|
||||||
<result column="model" property="model"/>
|
<result column="model" property="model"/>
|
||||||
<result column="brand" property="brand"/>
|
<result column="brand" property="brand"/>
|
||||||
|
<result column="name" property="name"/>
|
||||||
<result column="firmware_version" property="firmwareVersion"/>
|
<result column="firmware_version" property="firmwareVersion"/>
|
||||||
|
<result column="protocol_version" property="protocolVersion"/>
|
||||||
<result column="location" property="location"/>
|
<result column="location" property="location"/>
|
||||||
<result column="status" property="status"/>
|
<result column="status" property="status"/>
|
||||||
<result column="online_time" property="onlineTime"/>
|
<result column="print_status" property="printStatus"/>
|
||||||
<result column="offline_time" property="offlineTime"/>
|
<result column="error_status" property="errorStatus"/>
|
||||||
<result column="total_print_time" property="totalPrintTime"/>
|
|
||||||
<result column="remark" property="remark"/>
|
<result column="remark" property="remark"/>
|
||||||
<result column="type" property="type"/>
|
<result column="type" property="type"/>
|
||||||
<result column="create_by" property="createBy"/>
|
<result column="create_by" property="createBy"/>
|
||||||
@ -20,6 +22,11 @@
|
|||||||
<result column="update_time" property="updateTime"/>
|
<result column="update_time" property="updateTime"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
|
<update id="updateDeviceStatus">
|
||||||
|
update bus_device set status = #{status}, print_status = #{printStatus}, error_status = #{errorStatus}, remark = #{remark}
|
||||||
|
<where><if test="deviceSn != null and deviceSn != ''"> device_sn = #{deviceSn} </if></where>
|
||||||
|
</update>
|
||||||
|
|
||||||
<select id="getDevice" resultType="me.zhengjie.modules.system.domain.dto.BusTreeVo">
|
<select id="getDevice" resultType="me.zhengjie.modules.system.domain.dto.BusTreeVo">
|
||||||
select CONCAT('d', id) id, 0 pid, CONCAT('品牌:', brand, ' | ', '型号:', model) name, CONCAT(location, '[', IF(type=1, '3D打印机', '摄像头'), ']') remark,
|
select CONCAT('d', id) id, 0 pid, CONCAT('品牌:', brand, ' | ', '型号:', model) name, CONCAT(location, '[', IF(type=1, '3D打印机', '摄像头'), ']') remark,
|
||||||
(select count(*) from bus_device_command dc where dc.device_id = bus_device.id) subCount
|
(select count(*) from bus_device_command dc where dc.device_id = bus_device.id) subCount
|
||||||
@ -27,7 +34,7 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, device_sn, model, brand, firmware_version, location, status, online_time, offline_time, total_print_time, remark, type, create_by, update_by, create_time, update_time
|
id, device_code, device_sn, model, brand, name, firmware_version, protocol_version, location, status, print_status, error_status, remark, type, create_by, update_by, create_time, update_time
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="findAll" resultMap="BaseResultMap">
|
<select id="findAll" resultMap="BaseResultMap">
|
||||||
@ -39,6 +46,7 @@
|
|||||||
<if test="criteria.model != null and criteria.model != ''"> and model like concat('%', #{criteria.model}, '%') </if>
|
<if test="criteria.model != null and criteria.model != ''"> and model like concat('%', #{criteria.model}, '%') </if>
|
||||||
<if test="criteria.brand != null and criteria.brand != ''"> and brand like concat('%', #{criteria.brand}, '%') </if>
|
<if test="criteria.brand != null and criteria.brand != ''"> and brand like concat('%', #{criteria.brand}, '%') </if>
|
||||||
<if test="criteria.type != null"> and type = #{criteria.type} </if>
|
<if test="criteria.type != null"> and type = #{criteria.type} </if>
|
||||||
|
<if test="criteria.name != null"> and name like concat('%', #{criteria.name}, '%') </if>
|
||||||
</where>
|
</where>
|
||||||
order by id desc
|
order by id desc
|
||||||
</select>
|
</select>
|
||||||
|
Loading…
Reference in New Issue
Block a user