数据库修复: - t_user_health_data_daily: 添加customer_id字段(租户ID) - t_user_health_data_weekly: 添加customer_id字段(租户ID) ljwx-boot同步更新: - TUserHealthDataDailyMapper.xml: 添加customer_id字段映射 - TUserHealthDataWeeklyMapper.xml: 添加customer_id字段映射 其他改进: - 告警规则缓存优化 - Redis缓存性能提升 - 健康数据处理性能优化 - 添加完整的文档和工具脚本 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
19 KiB
19 KiB
基于实际代码的消息数据流集成方案
基于对ljwx-boot、ljwx-bigscreen、ljwx-phone、ljwx-watch四个平台的详细代码分析,提供一个贴合实际情况的消息数据流集成优化方案。
一、现有架构分析
1.1 数据库表结构(已存在)
t_device_message (主消息表)
CREATE TABLE t_device_message (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
device_sn VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
org_id VARCHAR(50),
user_id VARCHAR(50),
customer_id BIGINT NOT NULL DEFAULT 0,
message_type VARCHAR(50) NOT NULL, -- job/task/announcement/notification/system_alert
sender_type VARCHAR(50) NOT NULL, -- system/admin/user
receiver_type VARCHAR(50) NOT NULL, -- device/user/department
message_status VARCHAR(50) DEFAULT 'pending', -- pending/delivered/acknowledged
responded_number INTEGER DEFAULT 0,
sent_time DATETIME DEFAULT CURRENT_TIMESTAMP,
received_time DATETIME NULL,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
t_device_message_detail (消息详情表)
CREATE TABLE t_device_message_detail (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
message_id BIGINT NOT NULL,
device_sn VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
message_type VARCHAR(50) NOT NULL,
sender_type VARCHAR(50) NOT NULL,
receiver_type VARCHAR(50) NOT NULL,
message_status VARCHAR(50) DEFAULT 'pending',
sent_time DATETIME,
received_time DATETIME,
customer_id BIGINT NOT NULL,
org_id BIGINT,
-- 新增字段用于统计和跟踪
delivery_status VARCHAR(50), -- pending/delivered/acknowledged/failed/expired
channel VARCHAR(50), -- message/push/wechat/watch
response_time INTEGER, -- 响应时间(秒)
acknowledge_time DATETIME, -- 确认时间
target_type VARCHAR(50), -- user/device/department/organization
target_id VARCHAR(255) -- 目标ID
);
1.2 现有消息流程
ljwx-admin/ljwx-bigscreen → t_device_message → ljwx-phone → ljwx-watch
↓ (手动发送) ↓ (API查询) ↓ (蓝牙) ↓ (用户确认)
告警规则触发 定时获取消息 转发给手表 反向确认回传
二、各平台现状分析
2.1 ljwx-boot (Java后端)
现有接口:
TDeviceMessageController- CRUD操作DeviceMessageServiceImpl- 兼容性服务层- 支持消息的发送、接收、保存
优化需求:
- 增强消息生命周期管理
- 添加实时状态同步
- 支持批量操作和统计
2.2 ljwx-bigscreen (Python大屏)
现有功能:
DeviceMessage、DeviceMessageDetailSQLAlchemy模型/DeviceMessage/send、/receiveAPI接口- 告警自动转消息机制 (
system_event_alert.py) - 消息统计和展示功能
优化需求:
- 增强消息跟踪界面
- 实时状态更新
- 完善统计报表
2.3 ljwx-phone (Flutter移动端)
现有功能:
Message、MessageInfoDart模型ApiService.getDeviceMessages()- 获取消息markMessageAsRead()- 标记已读- 消息列表和详情UI
- 蓝牙消息转发给手表
优化需求:
- 实时消息推送
- 批量操作优化
- 离线消息同步
2.4 ljwx-watch (HarmonyOS手表)
现有功能:
- HTTP和蓝牙双模式消息接收
fetchMessageFromServer()- HTTP拉取- 蓝牙GATT命令处理
- 系统通知显示和用户确认
优化需求:
- 消息确认回传优化
- 显示效果增强
- 电池优化
三、集成优化方案
3.1 消息统一模型扩展
在现有数据库基础上增加字段,支持完整的消息生命周期:
-- 扩展 t_device_message 表
ALTER TABLE t_device_message ADD COLUMN title VARCHAR(500);
ALTER TABLE t_device_message ADD COLUMN content TEXT;
ALTER TABLE t_device_message ADD COLUMN priority INTEGER DEFAULT 3;
ALTER TABLE t_device_message ADD COLUMN urgency VARCHAR(20) DEFAULT 'medium';
ALTER TABLE t_device_message ADD COLUMN channels JSON; -- ["message","push","wechat","watch"]
ALTER TABLE t_device_message ADD COLUMN require_ack BOOLEAN DEFAULT false;
ALTER TABLE t_device_message ADD COLUMN expiry_time DATETIME;
ALTER TABLE t_device_message ADD COLUMN metadata JSON;
-- 扩展 t_device_message_detail 表
ALTER TABLE t_device_message_detail ADD COLUMN distribution_id VARCHAR(255);
ALTER TABLE t_device_message_detail ADD COLUMN target_type VARCHAR(50);
ALTER TABLE t_device_message_detail ADD COLUMN target_id VARCHAR(255);
ALTER TABLE t_device_message_detail ADD COLUMN delivery_status VARCHAR(50);
ALTER TABLE t_device_message_detail ADD COLUMN channel VARCHAR(50);
ALTER TABLE t_device_message_detail ADD COLUMN response_time INTEGER;
ALTER TABLE t_device_message_detail ADD COLUMN acknowledge_time DATETIME;
ALTER TABLE t_device_message_detail ADD COLUMN delivery_details JSON;
3.2 ljwx-boot 服务层增强
基于现有的 TDeviceMessageServiceImpl 扩展功能:
@Service
public class EnhancedMessageService extends TDeviceMessageServiceImpl {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 统一消息发布接口
*/
@Transactional
public Long publishMessage(UnifiedMessageRequest request) {
// 1. 保存主消息
TDeviceMessage message = buildDeviceMessage(request);
save(message);
// 2. 创建分发记录
List<TDeviceMessageDetail> details = createDistributionDetails(message, request);
messageDetailService.saveBatch(details);
// 3. 发布到Redis
publishToRedis(message, details);
// 4. 记录生命周期事件
recordLifecycleEvent(message.getId(), "created", getCurrentUser());
return message.getId();
}
/**
* 消息状态批量更新
*/
public void updateMessageStatus(Long messageId, String status, List<String> targetIds) {
// 更新主消息状态
TDeviceMessage message = getById(messageId);
message.setMessageStatus(status);
updateById(message);
// 更新详情状态
LambdaUpdateWrapper<TDeviceMessageDetail> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(TDeviceMessageDetail::getMessageId, messageId)
.in(TDeviceMessageDetail::getTargetId, targetIds)
.set(TDeviceMessageDetail::getDeliveryStatus, status)
.set(TDeviceMessageDetail::getAcknowledgeTime, LocalDateTime.now());
messageDetailService.update(wrapper);
// 发布状态更新事件
publishStatusUpdate(messageId, status);
}
private void publishToRedis(TDeviceMessage message, List<TDeviceMessageDetail> details) {
for (TDeviceMessageDetail detail : details) {
String channel = "message:" + detail.getChannel();
Map<String, Object> payload = buildRedisPayload(message, detail);
redisTemplate.convertAndSend(channel, payload);
}
}
}
3.3 ljwx-phone 实时消息集成
在现有Flutter代码基础上增加Redis订阅:
// lib/services/enhanced_message_service.dart
class EnhancedMessageService extends ApiService {
StreamSubscription<String>? _redisSubscription;
final StreamController<Message> _messageStreamController = StreamController<Message>.broadcast();
Stream<Message> get messageStream => _messageStreamController.stream;
@override
void initState() {
super.initState();
_subscribeToRedisMessages();
_startPeriodicSync(); // 保持现有的定时同步作为备用
}
void _subscribeToRedisMessages() {
// 订阅Redis消息通道
String channel = 'message:${deviceSn}';
_redisSubscription = RedisClient.subscribe(channel).listen((data) {
try {
Map<String, dynamic> messageData = jsonDecode(data);
Message message = Message.fromJson(messageData);
// 更新本地存储
_updateLocalMessage(message);
// 发布给UI层
_messageStreamController.add(message);
// 转发给手表(如果连接)
if (BluetoothService().isConnected) {
BluetoothService().forwardMessageToWatch(messageData);
}
} catch (e) {
print('解析Redis消息失败: $e');
}
});
}
@override
Future<bool> markMessageAsRead(String deviceSn, {
DateTime? receivedTime,
String? messageId,
Map<String, dynamic>? originalMessage
}) async {
// 调用现有API
final success = await super.markMessageAsRead(deviceSn,
receivedTime: receivedTime, messageId: messageId, originalMessage: originalMessage);
if (success) {
// 发布确认事件到Redis
Map<String, dynamic> ackEvent = {
'type': 'message_acknowledged',
'messageId': messageId,
'deviceSn': deviceSn,
'acknowledgeTime': receivedTime?.toIso8601String() ?? DateTime.now().toIso8601String(),
'source': 'phone'
};
RedisClient.publish('message:acknowledgments', jsonEncode(ackEvent));
}
return success;
}
}
3.4 ljwx-bigscreen 增强消息跟踪
基于现有的消息处理代码增加实时跟踪:
# bigScreen/enhanced_message_tracking.py
class EnhancedMessageTracker:
@staticmethod
def create_message_with_tracking(message_data):
"""创建消息并启用跟踪"""
try:
# 使用现有的DeviceMessage模型
message = DeviceMessage(
device_sn=message_data.get('device_sn'),
message=message_data.get('content'),
message_type=message_data.get('message_type', 'notification'),
sender_type=message_data.get('sender_type', 'admin'),
receiver_type=message_data.get('receiver_type', 'device'),
org_id=message_data.get('org_id'),
user_id=message_data.get('user_id'),
customer_id=message_data.get('customer_id', 0),
# 新增字段
title=message_data.get('title'),
priority=message_data.get('priority', 3),
urgency=message_data.get('urgency', 'medium'),
require_ack=message_data.get('require_ack', False),
channels=json.dumps(message_data.get('channels', ['message'])),
metadata=json.dumps(message_data.get('metadata', {}))
)
db.session.add(message)
db.session.commit()
# 创建分发记录
targets = message_data.get('targets', [])
for target in targets:
detail = DeviceMessageDetail(
message_id=message.id,
device_sn=target.get('device_sn'),
message=message.message,
message_type=message.message_type,
sender_type=message.sender_type,
receiver_type=message.receiver_type,
customer_id=message.customer_id,
org_id=message.org_id,
# 新增字段
target_type=target.get('target_type', 'device'),
target_id=target.get('target_id'),
delivery_status='pending',
channel=target.get('channel', 'message')
)
db.session.add(detail)
db.session.commit()
# 发布到Redis
redis_client.publish(f'message:created', json.dumps({
'messageId': message.id,
'targets': [detail.device_sn for detail in message.details]
}))
return message
except Exception as e:
db.session.rollback()
print(f"创建消息失败: {e}")
return None
@staticmethod
def get_message_lifecycle(message_id):
"""获取消息生命周期报告"""
message = DeviceMessage.query.get(message_id)
if not message:
return None
details = DeviceMessageDetail.query.filter_by(message_id=message_id).all()
# 计算统计数据
total_targets = len(details)
delivered = sum(1 for d in details if d.delivery_status in ['delivered', 'acknowledged'])
acknowledged = sum(1 for d in details if d.delivery_status == 'acknowledged')
pending = sum(1 for d in details if d.delivery_status == 'pending')
failed = sum(1 for d in details if d.delivery_status == 'failed')
# 计算响应时间
response_times = [d.response_time for d in details if d.response_time]
avg_response_time = sum(response_times) / len(response_times) if response_times else 0
return {
'messageId': message_id,
'messageType': message.message_type,
'createTime': message.create_time.isoformat(),
'sentTime': message.sent_time.isoformat() if message.sent_time else None,
'progress': {
'totalTargets': total_targets,
'delivered': delivered,
'acknowledged': acknowledged,
'pending': pending,
'failed': failed,
'completionRate': (acknowledged / total_targets * 100) if total_targets > 0 else 0,
'avgResponseTime': avg_response_time
},
'details': [
{
'targetId': d.target_id,
'deviceSn': d.device_sn,
'deliveryStatus': d.delivery_status,
'channel': d.channel,
'responseTime': d.response_time,
'acknowledgeTime': d.acknowledge_time.isoformat() if d.acknowledge_time else None
}
for d in details
]
}
# bigScreen.py 新增API端点
@app.route('/api/message/lifecycle/<int:message_id>', methods=['GET'])
def get_message_lifecycle(message_id):
"""获取消息生命周期"""
lifecycle_data = EnhancedMessageTracker.get_message_lifecycle(message_id)
if lifecycle_data:
return jsonify({'success': True, 'data': lifecycle_data})
else:
return jsonify({'success': False, 'error': '消息不存在'}), 404
@app.route('/api/message/stats/<int:org_id>', methods=['GET'])
def get_organization_message_stats(org_id):
"""获取组织消息统计"""
start_date = request.args.get('startDate')
end_date = request.args.get('endDate')
query = DeviceMessage.query.filter_by(org_id=str(org_id))
if start_date:
query = query.filter(DeviceMessage.create_time >= datetime.fromisoformat(start_date))
if end_date:
query = query.filter(DeviceMessage.create_time <= datetime.fromisoformat(end_date))
messages = query.all()
# 生成统计数据
stats = {
'totalMessages': len(messages),
'messageTypes': {},
'dailyTrend': {},
'avgCompletionRate': 0,
'avgResponseTime': 0
}
# ... 统计计算逻辑
return jsonify({'success': True, 'data': stats})
3.5 ljwx-watch 消息处理优化
基于现有的HTTP和蓝牙双模式,增加确认反馈优化:
// HttpService.java 消息确认增强
public void enhancedMessageConfirmation(JSONObject message) {
try {
String messageId = message.getString("message_id");
// 构建增强的确认响应
JSONObject enhancedResponse = new JSONObject();
enhancedResponse.put("type", "message_acknowledgment");
enhancedResponse.put("messageId", messageId);
enhancedResponse.put("deviceSn", dataManager.getDeviceSn());
enhancedResponse.put("acknowledgeTime", getCurrentTimestamp());
enhancedResponse.put("responseTime", calculateResponseTime(message));
enhancedResponse.put("channel", "http");
enhancedResponse.put("deviceInfo", getDeviceInfo());
enhancedResponse.put("userAction", "acknowledged"); // 用户主动确认
// 复制原消息字段
copyOriginalMessageFields(enhancedResponse, message);
// 发送确认
String confirmUrl = dataManager.getFetchMessageUrl() + "/acknowledge";
JSONObject response = postDataToServer(confirmUrl, enhancedResponse);
if (response != null && response.getBoolean("success")) {
Log.i(TAG, "✅ 消息确认发送成功: " + messageId);
// 本地标记为已确认
markMessageAsAcknowledged(messageId);
} else {
Log.w(TAG, "⚠️ 消息确认发送失败: " + messageId);
// 缓存确认,稍后重试
cacheAcknowledgment(enhancedResponse);
}
} catch (Exception e) {
Log.e(TAG, "❌ 消息确认处理异常: " + e.getMessage());
}
}
private int calculateResponseTime(JSONObject message) {
try {
String sentTimeStr = message.getString("sent_time");
long sentTime = parseTimestamp(sentTimeStr);
long currentTime = System.currentTimeMillis();
return (int) ((currentTime - sentTime) / 1000); // 返回秒数
} catch (Exception e) {
return -1; // 无法计算响应时间
}
}
private JSONObject getDeviceInfo() {
JSONObject deviceInfo = new JSONObject();
try {
deviceInfo.put("watchModel", "HarmonyOS Watch");
deviceInfo.put("osVersion", "4.0");
deviceInfo.put("appVersion", getAppVersion());
deviceInfo.put("batteryLevel", getBatteryLevel());
deviceInfo.put("signalStrength", getSignalStrength());
} catch (Exception e) {
Log.w(TAG, "获取设备信息失败: " + e.getMessage());
}
return deviceInfo;
}
四、实施路径
4.1 阶段一:数据库扩展(1周)
- 执行SQL脚本扩展现有表结构
- 更新ljwx-boot实体类
- 更新ljwx-bigscreen SQLAlchemy模型
- 数据迁移和兼容性测试
4.2 阶段二:后端服务增强(2周)
- ljwx-boot增强消息服务
- ljwx-bigscreen增强跟踪功能
- Redis集成和实时通信
- API接口联调测试
4.3 阶段三:移动端实时化(1周)
- ljwx-phone集成Redis订阅
- 增强消息确认机制
- 蓝牙通信优化
- 离线同步完善
4.4 阶段四:手表端优化(1周)
- ljwx-watch确认反馈增强
- 消息显示优化
- 电池性能优化
- 端到端测试
4.5 阶段五:整体联调(1周)
- 四端数据流测试
- 性能压力测试
- 用户体验优化
- 文档和培训
五、预期效果
- 完整数据流打通: 平台→手机→手表→确认回传的完整链路
- 实时状态同步: 基于Redis的实时消息推送和状态更新
- 全面生命周期跟踪: 从消息创建到确认完成的全流程监控
- 增强统计分析: 组织级、部门级、个人级的多维度分析
- 向后兼容: 保持现有API和数据结构的兼容性
此方案基于现有代码架构,最大程度复用已有功能,通过渐进式改进实现完整的消息数据流集成。