436 lines
9.7 KiB
Markdown
436 lines
9.7 KiB
Markdown
|
|
# 智能柜系统指南
|
|||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
智能柜系统是本项目的重要功能模块,用于管理智能储物柜设备,支持企业微信集成、格口操作、状态监控等功能。
|
|||
|
|
|
|||
|
|
## 功能特性
|
|||
|
|
|
|||
|
|
- ✅ 智能柜设备管理
|
|||
|
|
- ✅ 格口状态监控
|
|||
|
|
- ✅ 企业微信集成(支持corpid)
|
|||
|
|
- ✅ 格口操作(开锁、关锁、锁定)
|
|||
|
|
- ✅ 使用记录管理
|
|||
|
|
- ✅ 设备状态监控
|
|||
|
|
|
|||
|
|
## 数据库设计
|
|||
|
|
|
|||
|
|
### 智能柜表结构
|
|||
|
|
|
|||
|
|
#### smart_cabinet (智能柜表)
|
|||
|
|
```sql
|
|||
|
|
CREATE TABLE `smart_cabinet` (
|
|||
|
|
`id` bigint NOT NULL AUTO_INCREMENT,
|
|||
|
|
`cabinet_no` varchar(50) NOT NULL COMMENT '柜体编号',
|
|||
|
|
`name` varchar(100) NOT NULL COMMENT '柜体名称',
|
|||
|
|
`location` varchar(200) DEFAULT NULL COMMENT '安装位置',
|
|||
|
|
`status` tinyint DEFAULT '1' COMMENT '状态:1-正常 0-停用',
|
|||
|
|
`corpid` varchar(50) DEFAULT NULL COMMENT '企业微信id',
|
|||
|
|
`ip_address` varchar(50) DEFAULT NULL COMMENT 'IP地址',
|
|||
|
|
`port` int DEFAULT NULL COMMENT '端口',
|
|||
|
|
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
|
|||
|
|
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|||
|
|
PRIMARY KEY (`id`),
|
|||
|
|
UNIQUE KEY `uk_cabinet_no` (`cabinet_no`)
|
|||
|
|
);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### cabinet_cell (柜体格口表)
|
|||
|
|
```sql
|
|||
|
|
CREATE TABLE `cabinet_cell` (
|
|||
|
|
`id` bigint NOT NULL AUTO_INCREMENT,
|
|||
|
|
`cabinet_id` bigint NOT NULL COMMENT '柜体ID',
|
|||
|
|
`cell_no` varchar(20) NOT NULL COMMENT '格口编号',
|
|||
|
|
`cell_type` varchar(20) DEFAULT 'SMALL' COMMENT '格口类型:SMALL-小格 LARGE-大格',
|
|||
|
|
`status` tinyint DEFAULT '1' COMMENT '状态:1-空闲 2-占用 3-故障',
|
|||
|
|
`current_order_id` bigint DEFAULT NULL COMMENT '当前订单ID',
|
|||
|
|
`lock_status` tinyint DEFAULT '0' COMMENT '锁状态:0-关闭 1-开启',
|
|||
|
|
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
|
|||
|
|
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|||
|
|
PRIMARY KEY (`id`),
|
|||
|
|
KEY `idx_cabinet_id` (`cabinet_id`),
|
|||
|
|
KEY `idx_cell_no` (`cell_no`)
|
|||
|
|
);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### cabinet_cell_operation (格口操作记录表)
|
|||
|
|
```sql
|
|||
|
|
CREATE TABLE `cabinet_cell_operation` (
|
|||
|
|
`id` bigint NOT NULL AUTO_INCREMENT,
|
|||
|
|
`cabinet_id` bigint NOT NULL COMMENT '柜体ID',
|
|||
|
|
`cell_id` bigint NOT NULL COMMENT '格口ID',
|
|||
|
|
`operation_type` varchar(20) NOT NULL COMMENT '操作类型:OPEN-开锁 CLOSE-关锁 LOCK-锁定',
|
|||
|
|
`operator_id` bigint DEFAULT NULL COMMENT '操作员ID',
|
|||
|
|
`operator_type` varchar(20) DEFAULT NULL COMMENT '操作员类型:USER-用户 ADMIN-管理员',
|
|||
|
|
`result` tinyint DEFAULT '1' COMMENT '操作结果:1-成功 0-失败',
|
|||
|
|
`error_msg` varchar(500) DEFAULT NULL COMMENT '错误信息',
|
|||
|
|
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
|
|||
|
|
PRIMARY KEY (`id`),
|
|||
|
|
KEY `idx_cabinet_cell` (`cabinet_id`, `cell_id`),
|
|||
|
|
KEY `idx_create_time` (`create_time`)
|
|||
|
|
);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## API接口
|
|||
|
|
|
|||
|
|
### 1. 柜体管理
|
|||
|
|
|
|||
|
|
#### 1.1 获取柜体列表
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
GET /cabinet/list?pageNum=1&pageSize=10
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**响应**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"msg": "success",
|
|||
|
|
"data": {
|
|||
|
|
"total": 5,
|
|||
|
|
"rows": [
|
|||
|
|
{
|
|||
|
|
"id": 1,
|
|||
|
|
"cabinetNo": "CAB001",
|
|||
|
|
"name": "一号智能柜",
|
|||
|
|
"location": "一楼大厅",
|
|||
|
|
"status": 1,
|
|||
|
|
"corpid": "ww1234567890abcdef",
|
|||
|
|
"ipAddress": "192.168.1.100",
|
|||
|
|
"port": 8080,
|
|||
|
|
"totalCells": 24,
|
|||
|
|
"freeCells": 18,
|
|||
|
|
"createTime": "2025-03-08 10:00:00"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 1.2 新增柜体
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
POST /cabinet
|
|||
|
|
Content-Type: application/json
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"cabinetNo": "CAB002",
|
|||
|
|
"name": "二号智能柜",
|
|||
|
|
"location": "二楼走廊",
|
|||
|
|
"corpid": "ww1234567890abcdef",
|
|||
|
|
"ipAddress": "192.168.1.101",
|
|||
|
|
"port": 8080
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 1.3 修改柜体
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
PUT /cabinet/{cabinetId}
|
|||
|
|
Content-Type: application/json
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"name": "二号智能柜(更新)",
|
|||
|
|
"location": "二楼东侧走廊",
|
|||
|
|
"status": 1
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 格口管理
|
|||
|
|
|
|||
|
|
#### 2.1 获取格口列表
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
GET /cabinet/{cabinetId}/cells?pageNum=1&pageSize=20
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**响应**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"msg": "success",
|
|||
|
|
"data": {
|
|||
|
|
"total": 24,
|
|||
|
|
"rows": [
|
|||
|
|
{
|
|||
|
|
"id": 1,
|
|||
|
|
"cellNo": "A01",
|
|||
|
|
"cellType": "SMALL",
|
|||
|
|
"status": 1,
|
|||
|
|
"lockStatus": 0,
|
|||
|
|
"currentOrderId": null,
|
|||
|
|
"createTime": "2025-03-08 10:00:00"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2.2 格口操作
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
POST /cabinet/cell/operate
|
|||
|
|
Content-Type: application/json
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"cabinetId": 1,
|
|||
|
|
"cellId": 1,
|
|||
|
|
"operation": "open",
|
|||
|
|
"operatorId": 1001,
|
|||
|
|
"operatorType": "USER"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**操作类型**:
|
|||
|
|
- `open`: 开锁
|
|||
|
|
- `close`: 关锁
|
|||
|
|
- `lock`: 锁定
|
|||
|
|
|
|||
|
|
### 3. 操作记录
|
|||
|
|
|
|||
|
|
#### 3.1 获取操作记录
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
GET /cabinet/operation/logs?cabinetId=1&cellId=1&pageNum=1&pageSize=10
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 企业微信集成
|
|||
|
|
|
|||
|
|
### 1. corpid字段说明
|
|||
|
|
|
|||
|
|
`corpid`字段用于关联企业微信应用,支持以下功能:
|
|||
|
|
- 企业微信用户身份验证
|
|||
|
|
- 企业微信消息推送
|
|||
|
|
- 企业微信扫码开柜
|
|||
|
|
- 企业微信审批流程
|
|||
|
|
|
|||
|
|
### 2. 企业微信扫码开柜
|
|||
|
|
|
|||
|
|
#### 2.1 生成开柜二维码
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
GET /cabinet/{cabinetId}/qrcode
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**响应**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"msg": "success",
|
|||
|
|
"data": {
|
|||
|
|
"qrcodeUrl": "https://qyapi.weixin.qq.com/cgi-bin/qrcode?ticket=xxx",
|
|||
|
|
"expireTime": "2025-03-08 11:00:00"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2.2 企业微信回调处理
|
|||
|
|
|
|||
|
|
当用户扫描二维码后,企业微信会回调到配置的URL:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
POST /qywx/cabinet/callback
|
|||
|
|
Content-Type: application/xml
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**回调数据**:
|
|||
|
|
```xml
|
|||
|
|
<xml>
|
|||
|
|
<ToUserName><![CDATA[toUser]]></ToUserName>
|
|||
|
|
<FromUserName><![CDATA[fromUser]]></FromUserName>
|
|||
|
|
<CreateTime>1348831860</CreateTime>
|
|||
|
|
<MsgType><![CDATA[event]]></MsgType>
|
|||
|
|
<Event><![CDATA[SCAN]]></Event>
|
|||
|
|
<EventKey><![CDATA[CAB001_A01]]></EventKey>
|
|||
|
|
<Ticket><![CDATA[gQH47joAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL2taZ2Z3TVRtNzJXV1Brb3ZhYmJJAAIEZ23sUwMEmm3sUw==]]></Ticket>
|
|||
|
|
</xml>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 设备通信协议
|
|||
|
|
|
|||
|
|
### 1. TCP通信协议
|
|||
|
|
|
|||
|
|
智能柜设备通过TCP协议与系统通信:
|
|||
|
|
|
|||
|
|
#### 1.1 开锁指令
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
指令格式: OPEN|{cabinetNo}|{cellNo}|{timestamp}|{sign}
|
|||
|
|
示例: OPEN|CAB001|A01|1657794651|BDF0099C9FF443C4DC5C5D68C4B97C3F
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 1.2 关锁指令
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
指令格式: CLOSE|{cabinetNo}|{cellNo}|{timestamp}|{sign}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 1.3 状态查询
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
指令格式: STATUS|{cabinetNo}|{timestamp}|{sign}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 签名算法
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
public class CabinetSignUtils {
|
|||
|
|
|
|||
|
|
public static String generateSign(String cabinetNo, String cellNo, long timestamp, String secret) {
|
|||
|
|
String content = cabinetNo + "|" + cellNo + "|" + timestamp + "|" + secret;
|
|||
|
|
return DigestUtils.md5Hex(content).toUpperCase();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static boolean verifySign(String cabinetNo, String cellNo, long timestamp, String sign, String secret) {
|
|||
|
|
String expectedSign = generateSign(cabinetNo, cellNo, timestamp, secret);
|
|||
|
|
return expectedSign.equals(sign);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 业务逻辑
|
|||
|
|
|
|||
|
|
### 1. 开柜流程
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@Service
|
|||
|
|
@RequiredArgsConstructor
|
|||
|
|
public class CabinetService {
|
|||
|
|
|
|||
|
|
private final CabinetDeviceClient deviceClient;
|
|||
|
|
private final CabinetCellOperationService operationService;
|
|||
|
|
|
|||
|
|
@Transactional
|
|||
|
|
public void openCell(Long cabinetId, Long cellId, Long operatorId, String operatorType) {
|
|||
|
|
// 1. 验证柜体和格口状态
|
|||
|
|
CabinetCell cell = validateCellStatus(cabinetId, cellId);
|
|||
|
|
|
|||
|
|
// 2. 发送开锁指令
|
|||
|
|
boolean success = deviceClient.sendOpenCommand(cell.getCabinetNo(), cell.getCellNo());
|
|||
|
|
|
|||
|
|
// 3. 记录操作日志
|
|||
|
|
CabinetCellOperation operation = createOperationLog(
|
|||
|
|
cabinetId, cellId, "OPEN", operatorId, operatorType, success
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
// 4. 更新格口状态
|
|||
|
|
if (success) {
|
|||
|
|
updateCellLockStatus(cellId, 1); // 锁开启
|
|||
|
|
} else {
|
|||
|
|
throw new ApiException("开锁失败,请重试");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 状态监控
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@Service
|
|||
|
|
@RequiredArgsConstructor
|
|||
|
|
public class CabinetMonitorService {
|
|||
|
|
|
|||
|
|
@Scheduled(fixedRate = 30000) // 每30秒执行一次
|
|||
|
|
public void monitorCabinetStatus() {
|
|||
|
|
List<SmartCabinet> cabinets = cabinetService.getAllActiveCabinets();
|
|||
|
|
|
|||
|
|
for (SmartCabinet cabinet : cabinets) {
|
|||
|
|
try {
|
|||
|
|
// 查询设备状态
|
|||
|
|
CabinetStatus status = deviceClient.queryStatus(cabinet.getCabinetNo());
|
|||
|
|
|
|||
|
|
// 更新数据库状态
|
|||
|
|
updateCabinetStatus(cabinet.getId(), status);
|
|||
|
|
|
|||
|
|
// 记录监控日志
|
|||
|
|
logMonitorResult(cabinet.getId(), status, true);
|
|||
|
|
|
|||
|
|
} catch (Exception e) {
|
|||
|
|
// 设备连接失败
|
|||
|
|
logMonitorResult(cabinet.getId(), null, false);
|
|||
|
|
log.error("监控柜体{}状态失败: {}", cabinet.getCabinetNo(), e.getMessage());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 配置管理
|
|||
|
|
|
|||
|
|
### 1. 设备配置
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
cabinet:
|
|||
|
|
device:
|
|||
|
|
timeout: 5000
|
|||
|
|
retry-count: 3
|
|||
|
|
heartbeat-interval: 30000
|
|||
|
|
reconnect-interval: 10000
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 企业微信配置
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
qywx:
|
|||
|
|
cabinet:
|
|||
|
|
enabled: true
|
|||
|
|
callback-url: https://your-domain.com/qywx/cabinet/callback
|
|||
|
|
qrcode-expire: 300
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 安全考虑
|
|||
|
|
|
|||
|
|
### 1. 通信安全
|
|||
|
|
- TCP通信使用TLS加密
|
|||
|
|
- 指令签名验证
|
|||
|
|
- 防止重放攻击
|
|||
|
|
- IP白名单控制
|
|||
|
|
|
|||
|
|
### 2. 业务安全
|
|||
|
|
- 操作权限验证
|
|||
|
|
- 操作频率限制
|
|||
|
|
- 异常操作告警
|
|||
|
|
- 操作日志审计
|
|||
|
|
|
|||
|
|
### 3. 数据安全
|
|||
|
|
- 敏感数据加密存储
|
|||
|
|
- 数据库访问权限控制
|
|||
|
|
- 定期数据备份
|
|||
|
|
- 操作日志保留
|
|||
|
|
|
|||
|
|
## 故障处理
|
|||
|
|
|
|||
|
|
### 1. 设备离线
|
|||
|
|
- 自动重连机制
|
|||
|
|
- 状态告警通知
|
|||
|
|
- 手动干预流程
|
|||
|
|
|
|||
|
|
### 2. 通信异常
|
|||
|
|
- 超时重试机制
|
|||
|
|
- 异常日志记录
|
|||
|
|
- 人工排查流程
|
|||
|
|
|
|||
|
|
### 3. 数据不一致
|
|||
|
|
- 状态同步机制
|
|||
|
|
- 数据修复工具
|
|||
|
|
- 手动核对流程
|
|||
|
|
|
|||
|
|
## 监控告警
|
|||
|
|
|
|||
|
|
### 1. 监控指标
|
|||
|
|
- 设备在线率
|
|||
|
|
- 操作成功率
|
|||
|
|
- 响应时间
|
|||
|
|
- 错误率
|
|||
|
|
|
|||
|
|
### 2. 告警规则
|
|||
|
|
- 设备离线超过5分钟
|
|||
|
|
- 操作失败率超过10%
|
|||
|
|
- 响应时间超过3秒
|
|||
|
|
- 连续错误次数超过3次
|
|||
|
|
|
|||
|
|
### 3. 告警方式
|
|||
|
|
- 企业微信消息
|
|||
|
|
- 短信通知
|
|||
|
|
- 邮件通知
|
|||
|
|
- 系统日志
|