From 8ea1150825b4aedc2defdb721a937b5ecdb55ebb Mon Sep 17 00:00:00 2001 From: luoyuehang <2830398107@qq.com> Date: Mon, 13 Oct 2025 20:28:49 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=E7=BD=97=E6=9C=88=E8=88=AA=E7=9A=84?= =?UTF-8?q?=E7=AC=AC=E5=9B=9B=E5=91=A8=E5=91=A8=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../members/luoyuehang-weekly-plan-4.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 doc/process/weekly/week-4/members/luoyuehang-weekly-plan-4.md diff --git a/doc/process/weekly/week-4/members/luoyuehang-weekly-plan-4.md b/doc/process/weekly/week-4/members/luoyuehang-weekly-plan-4.md new file mode 100644 index 0000000..41d9ed7 --- /dev/null +++ b/doc/process/weekly/week-4/members/luoyuehang-weekly-plan-4.md @@ -0,0 +1,23 @@ +# 个人周计划-第1周 + +## 姓名和起止时间 + +**姓  名:** 罗月航 +**团队名称:** 1班-汪汪队 +**开始时间:** 2025-10-13 +**结束时间:** 2025-10-19 + +## 本周任务计划安排 + +| 序号 | 计划内容 | 协作人 | 情况说明 | +| ---- | -------- | ------ | -------- | +| 1 | 需求分析与理解 | 组员 | 仔细阅读项目需求文档,理解管理员、维修人员、学生三类用户的功能需求 | +| 2 | 设计规范制定 | 组员 | 与协作者共同确定Web端与移动端的设计风格、色彩体系和组件规范 | +| 3 | 维修人员APP原型设计 | 个人 | 完成维修人员APP核心页面(设备监控、工单处理)的线框图和高保真设计 | +| 4 | 管理员平台协作设计 | 组员 | 协助完成管理员平台中"工单跟踪"与"人员管理"模块的UI设计 | +| 5 | 设计评审与优化 | 组员 | 参与内部设计评审,根据反馈意见优化完善UI设计方案 | + +## 小结 + + **协作沟通:** 希望建立定期的设计评审机制,确保设计方向的一致性。 + From 09ad03df4100c7fba4d59bee426dc51a2e9660ea Mon Sep 17 00:00:00 2001 From: wanglei <3085637232@qq.com> Date: Mon, 13 Oct 2025 20:53:49 +0800 Subject: [PATCH 02/12] =?UTF-8?q?=E7=8E=8B=E7=A3=8A=E7=9A=84=E7=AC=AC?= =?UTF-8?q?=E5=9B=9B=E5=91=A8=E4=B8=AA=E4=BA=BA=E5=91=A8=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../week-4/members/wanglei-weekly-plan-4.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 doc/process/weekly/week-4/members/wanglei-weekly-plan-4.md diff --git a/doc/process/weekly/week-4/members/wanglei-weekly-plan-4.md b/doc/process/weekly/week-4/members/wanglei-weekly-plan-4.md new file mode 100644 index 0000000..fb670c9 --- /dev/null +++ b/doc/process/weekly/week-4/members/wanglei-weekly-plan-4.md @@ -0,0 +1,33 @@ +# 个人周计划-第4周 + +## 姓名和起止时间 + +**姓  名:** 王磊 +**团队名称:** 1班-汪汪队 +**开始时间:** 2023-10-13 +**结束时间:** 2023-10-19 + + +## 本周任务计划安排 + +|序号| 计划内容| 协作人 | 情况说明 | +| ---- | ------ | ------| ------- | +| 1 | 需求获取 | 组员 | 2025-10-10 与肖雄仁老师面对面沟通确定需求 | +| 2 | 学习 | 个人 | 周内持续学习搭建数据库和处理数据的相关知识 | +| 3 | 确定分工 | 组员 | 2025-10-10 开会细分确定团队分工, | +| 4 | 学习项目的相关知识 | 个人 | 周内持续学习数据库的相关知识 | + +## 小结 + +1. **学习需求:** 学习数据库相关知识和处理数据; +2. **知识储备:** 提前学习后续需要使用的知识,为后续的前端开发做准备; +3. **文档撰写:** 结合课内知识学习需求文档的撰写。 + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +1. 请将个人计划和总结提前发给负责人; +1. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +1. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台; \ No newline at end of file From ab5bd5bc490f5e4233094edabd5c6d2128f4a05b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E7=AB=9E=E7=94=B1?= <1193626695@qq.com> Date: Mon, 13 Oct 2025 21:11:51 +0800 Subject: [PATCH 03/12] =?UTF-8?q?=E5=91=A8=E7=AB=9E=E7=94=B1=E7=9A=84?= =?UTF-8?q?=E7=AC=AC=E5=9B=9B=E5=91=A8=E5=91=A8=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../members/zhoujingyou-weekly-plan-4.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md diff --git a/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md b/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md new file mode 100644 index 0000000..9205055 --- /dev/null +++ b/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md @@ -0,0 +1,24 @@ +# 个人周计划-第1周 + +## 姓名和起止时间 + +**姓  名:** [您的姓名] +**团队名称:** [您的团队名称] +**开始时间:** 2025-10-13 +**结束时间:** 2025-10-19 + +## 本周任务计划安排 + +| 序号 | 计划内容 | 协作人 | 情况说明 | +|----|--------------------------------|-----|-------------------------------| +| 1 | 分析需求文档并与团队沟通,明确前端设计的核心功能模块 | 组员 | 2025-10-13 阅读需求文档并与设计团队确认需求细节 | +| 2 | 制定UI设计方案,规划学生端、维修人员端和Web端的界面风格 | 个人 | 设计草图和布局框架,确保与需求一致 | +| 3 | 完成首页和功能模块的初步UI设计,关注色彩、字体和布局 | 个人 | 完成首页UI设计,并与团队进行初步评审 | +| 4 | 继续完善学生端APP的UI设计,加入动画效果和交互细节 | 个人 | 根据反馈继续调整设计,优化交互效果 | +| 5 | 开始前端页面布局开发,使用HTML & CSS编写基本结构 | 个人 | 搭建学生端的基础页面布局,并与后端接口对接 | + +## 小结 + +1. **学习需求:** 希望能有更多关于UI设计与前端开发工具的支持和学习资源; +2. **知识储备:** 提前学习前端开发的相关技能,包括HTML、CSS、JavaScript的基础与进阶知识; +3. **文档撰写:** 完成需求分析与前端设计方案,并与团队保持密切沟通,确保所有开发内容一致。 From 6c5ecfe8e0409e8bee0417341d47eaabe7e8eb89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E7=AB=9E=E7=94=B1?= <1193626695@qq.com> Date: Mon, 13 Oct 2025 21:15:01 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E5=91=A8=E7=AB=9E=E7=94=B1=E7=9A=84?= =?UTF-8?q?=E7=AC=AC=E5=9B=9B=E5=91=A8=E5=91=A8=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weekly/week-4/members/zhoujingyou-weekly-plan-4.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md b/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md index 9205055..64cba72 100644 --- a/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md +++ b/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md @@ -2,8 +2,8 @@ ## 姓名和起止时间 -**姓  名:** [您的姓名] -**团队名称:** [您的团队名称] +**姓  名:** 周竞由 +**团队名称:** 软1-汪汪队 **开始时间:** 2025-10-13 **结束时间:** 2025-10-19 From 63380d7d3739c1e1094570986d7ca5db7946f9fb Mon Sep 17 00:00:00 2001 From: tianyuan <2861334240@qq.com> Date: Sat, 18 Oct 2025 00:54:12 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=BC=A0=E8=BE=93?= =?UTF-8?q?=E9=83=A8=E5=88=86=E8=8D=89=E7=A8=BF1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/manage-web/MonitorController.java | 43 +++++++++++ src/manage-web/WebMqttConfig.java | 42 +++++++++++ src/manage-web/WebMqttSubscriber.java | 54 ++++++++++++++ src/mqtt-server/DataForwarder.java | 86 ++++++++++++++++++++++ src/mqtt-server/MqttConfig.java | 53 +++++++++++++ src/mqtt-server/MqttSubscriber.java | 73 ++++++++++++++++++ src/repair-app/ RepairMqttSubscriber.java | 62 ++++++++++++++++ src/repair-app/RepairMqttConfig.java | 43 +++++++++++ src/repair-app/WorkOrderController.java | 53 +++++++++++++ src/student-app/ StudentMqttConfig.java | 39 ++++++++++ src/student-app/DrinkController.java | 49 ++++++++++++ src/student-app/StudentMqttSubscriber.java | 45 +++++++++++ 12 files changed, 642 insertions(+) create mode 100644 src/manage-web/MonitorController.java create mode 100644 src/manage-web/WebMqttConfig.java create mode 100644 src/manage-web/WebMqttSubscriber.java create mode 100644 src/mqtt-server/DataForwarder.java create mode 100644 src/mqtt-server/MqttConfig.java create mode 100644 src/mqtt-server/MqttSubscriber.java create mode 100644 src/repair-app/ RepairMqttSubscriber.java create mode 100644 src/repair-app/RepairMqttConfig.java create mode 100644 src/repair-app/WorkOrderController.java create mode 100644 src/student-app/ StudentMqttConfig.java create mode 100644 src/student-app/DrinkController.java create mode 100644 src/student-app/StudentMqttSubscriber.java diff --git a/src/manage-web/MonitorController.java b/src/manage-web/MonitorController.java new file mode 100644 index 0000000..441d1f5 --- /dev/null +++ b/src/manage-web/MonitorController.java @@ -0,0 +1,43 @@ +package com.campus.water.web.controller; + +import com.campus.water.web.entity.SensorDataWebVO; +import com.campus.water.web.service.RealTimeService; +import com.campus.water.web.service.HistoryDataService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 监控数据接口(供Web前端Vue调用,适配管理员“监控设备数据”需求) + */ +@RestController +@RequestMapping("/api/admin/monitor") +public class MonitorController { + @Autowired + private RealTimeService realTimeService; + @Autowired + private HistoryDataService historyDataService; + + // 1. 获取单设备实时数据(适配前端设备详情页) + @GetMapping("/realTime/{deviceId}") + public SensorDataWebVO getRealTimeData(@PathVariable String deviceId) { + return realTimeService.getRealTimeData(deviceId); + } + + // 2. 获取全量设备实时状态(适配前端监控总览页) + @GetMapping("/realTime/all") + public List getAllRealTimeData() { + return realTimeService.getAllRealTimeData(); + } + + // 3. 获取设备历史数据(适配前端历史曲线,需求中“查看历史水质”) + @GetMapping("/history/{deviceId}") + public List getHistoryData( + @PathVariable String deviceId, + @RequestParam String startTime, // 开始时间(如2024-05-20 00:00:00) + @RequestParam String endTime // 结束时间 + ) { + return historyDataService.getHistoryData(deviceId, startTime, endTime); + } +} \ No newline at end of file diff --git a/src/manage-web/WebMqttConfig.java b/src/manage-web/WebMqttConfig.java new file mode 100644 index 0000000..404c953 --- /dev/null +++ b/src/manage-web/WebMqttConfig.java @@ -0,0 +1,42 @@ +package com.campus.water.web.config; + +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 管理Web端MQTT配置(订阅MQTT服务器转发的全量数据,适配管理员监控需求) + */ +@Configuration +public class WebMqttConfig { + // MQTT服务器转发的主题前缀(需求中全量设备数据/告警) + private String mqttBroker = "tcp://mqtt-server.campus.com:1883"; + private String clientId = "campus-water-admin-web"; // Web端客户端ID + + @Bean + public MqttClient mqttClient() throws Exception { + MqttClient client = new MqttClient(mqttBroker, clientId, new MemoryPersistence()); + MqttConnectOptions options = new MqttConnectOptions(); + options.setCleanSession(false); + options.setKeepAliveInterval(60); + client.connect(options); + System.out.println("管理Web已连接MQTT服务器:" + mqttBroker); + return client; + } + + // 订阅的主题(全量设备数据+全量告警,适配管理员权限) + @Bean + public String[] subscribeTopics() { + return new String[]{ + "forward/web/device/#", // 全量设备实时数据 + "forward/web/alert/#" // 全量告警报文 + }; + } + + @Bean + public int[] qosLevels() { + return new int[]{0, 1}; // 告警QoS=1,设备数据QoS=0 + } +} \ No newline at end of file diff --git a/src/manage-web/WebMqttSubscriber.java b/src/manage-web/WebMqttSubscriber.java new file mode 100644 index 0000000..3881249 --- /dev/null +++ b/src/manage-web/WebMqttSubscriber.java @@ -0,0 +1,54 @@ +package com.campus.water.web.mqtt; + +import com.alibaba.fastjson2.JSONObject; +import com.campus.water.web.entity.SensorDataWebVO; +import com.campus.water.web.entity.AlertWebVO; +import com.campus.water.web.service.RealTimeService; +import org.eclipse.paho.client.mqttv3.IMqttMessageListener; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +/** + * 管理Web端MQTT订阅器(接收实时设备数据/告警,适配管理员监控需求) + */ +@Component +public class WebMqttSubscriber { + @Autowired + private MqttClient mqttClient; + @Autowired + private String[] subscribeTopics; + @Autowired + private int[] qosLevels; + @Autowired + private RealTimeService realTimeService; + + @PostConstruct + public void startSubscribe() throws Exception { + for (int i = 0; i < subscribeTopics.length; i++) { + String topic = subscribeTopics[i]; + int qos = qosLevels[i]; + mqttClient.subscribe(topic, qos, messageListener()); + System.out.println("管理Web已订阅主题:" + topic); + } + } + + private IMqttMessageListener messageListener() { + return (topic, message) -> { + String payload = new String(message.getPayload()); + System.out.println("管理Web接收数据:主题=" + topic + ",内容=" + payload); + + // 解析数据并缓存到内存(供前端轮询获取实时数据) + if (topic.startsWith("forward/web/device/")) { + SensorDataWebVO sensorVO = JSONObject.parseObject(payload, SensorDataWebVO.class); + realTimeService.updateRealTimeData(sensorVO); // 缓存实时数据 + } else if (topic.startsWith("forward/web/alert/")) { + AlertWebVO alertVO = JSONObject.parseObject(payload, AlertWebVO.class); + realTimeService.addAlert(alertVO); // 缓存告警(前端告警列表实时更新) + } + }; + } +} \ No newline at end of file diff --git a/src/mqtt-server/DataForwarder.java b/src/mqtt-server/DataForwarder.java new file mode 100644 index 0000000..bbd4dcf --- /dev/null +++ b/src/mqtt-server/DataForwarder.java @@ -0,0 +1,86 @@ +package com.campus.water.mqtt.core; + +import com.alibaba.fastjson2.JSONObject; +import com.campus.water.mqtt.entity.SensorData; +import com.campus.water.mqtt.entity.AlertMessage; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 数据转发器(按需求转发到管理Web/学生APP/维修APP,实现多端数据同步) + */ +@Component +public class DataForwarder { + @Autowired + private MqttClient mqttClient; + + // 1. 转发传感器数据到管理Web(全量数据,适配管理员监控需求) + public void forwardToWeb(SensorData sensorData) throws Exception { + String topic = "forward/web/device/" + sensorData.getDeviceId(); + String payload = JSONObject.toJSONString(sensorData); + publish(topic, payload, 0); // Web端QoS=0(普通监控数据) + } + + // 2. 转发告警到管理Web(适配管理员查看告警需求) + public void forwardToWeb(AlertMessage alert) throws Exception { + String topic = "forward/web/alert/" + alert.getDeviceId(); + String payload = JSONObject.toJSONString(alert); + publish(topic, payload, 1); // 告警QoS=1(确保管理员看到) + } + + // 3. 转发制水机水质数据到学生APP(仅终端机关联的制水机,适配查水质需求) + public void forwardToStudentApp(SensorData sensorData) throws Exception { + // 仅制水机数据需转发(学生APP查水质) + if (sensorData.getDeviceType() != 1) return; + + // 按终端机ID转发(需求中学生扫码查对应终端机的水质) + String terminalId = getRelatedTerminalId(sensorData.getDeviceId()); + String topic = "forward/student/terminal/" + terminalId; + String payload = JSONObject.toJSONString(new JSONObject() {{ + put("terminalId", terminalId); + put("tdsValue", sensorData.getTdsValue()); + put("waterQuality", getWaterQuality(sensorData.getTdsValue())); // 水质等级 + put("timestamp", sensorData.getTimestamp()); + }}); + publish(topic, payload, 0); + } + + // 4. 转发供水机水位/告警到维修APP(仅本辖区设备,适配维修员权限需求) + public void forwardToRepairApp(SensorData sensorData) throws Exception { + String areaId = sensorData.getAreaId(); // 设备所属片区(如AREA01) + String topic = "forward/repair/area/" + areaId + "/device/" + sensorData.getDeviceId(); + String payload = JSONObject.toJSONString(sensorData); + publish(topic, payload, 0); + } + + public void forwardToRepairApp(AlertMessage alert) throws Exception { + String areaId = alert.getAreaId(); + String topic = "forward/repair/area/" + areaId + "/alert/" + alert.getDeviceId(); + String payload = JSONObject.toJSONString(alert); + publish(topic, payload, 1); // 告警QoS=1(确保维修员抢单) + } + + // 通用发布方法 + private void publish(String topic, String payload, int qos) throws Exception { + MqttMessage message = new MqttMessage(payload.getBytes()); + message.setQos(qos); + mqttClient.publish(topic, message); + System.out.println("MQTT服务器转发数据:主题=" + topic + ",内容=" + payload); + } + + // 工具方法:根据制水机ID获取关联的终端机ID(需求中终端机关联制水机) + private String getRelatedTerminalId(String deviceId) { + // 实际需从MySQL设备表查询,此处模拟(如制水机WM001关联终端机TERM001/TERM002) + return deviceId.equals("WM001") ? "TERM001" : "TERM002"; + } + + // 工具方法:根据TDS值判断水质等级(需求中“优质矿化水”标准) + private String getWaterQuality(double tds) { + if (tds < 50) return "纯净水(无矿物质)"; + else if (tds < 300) return "优质矿化水"; + else if (tds < 600) return "合格矿化水"; + else return "水质超标(不建议饮用)"; + } +} \ No newline at end of file diff --git a/src/mqtt-server/MqttConfig.java b/src/mqtt-server/MqttConfig.java new file mode 100644 index 0000000..0f060f6 --- /dev/null +++ b/src/mqtt-server/MqttConfig.java @@ -0,0 +1,53 @@ +package com.campus.water.mqtt.config; + +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Properties; + +/** + * MQTT服务器配置(适配需求中Air724模块数据上传,对接MQTT Broker) + */ +@Configuration +public class MqttConfig { + // 从配置文件读取Broker地址(需求中云端Broker,如EMQX) + private String brokerUrl = "tcp://mqtt-server.campus.com:1883"; + private String clientId = "campus-water-mqtt-server"; // 服务器端客户端ID + private int keepAlive = 60; // 心跳间隔(秒),适配Air724模块低功耗 + + @Bean + public MqttClient mqttClient() throws Exception { + // 1. 创建MQTT客户端(内存持久化,避免服务器存储压力) + MqttClient client = new MqttClient(brokerUrl, clientId, new MemoryPersistence()); + + // 2. 配置连接参数(确保数据可靠传输,适配需求中告警不丢失) + MqttConnectOptions options = new MqttConnectOptions(); + options.setCleanSession(false); // 保持会话,重连后恢复订阅 + options.setKeepAliveInterval(keepAlive); + options.setAutomaticReconnect(true); // 自动重连,适配网络波动 + + // 3. 连接Broker + client.connect(options); + System.out.println("MQTT服务器已连接Broker:" + brokerUrl); + return client; + } + + // 订阅的主题(严格按需求中设备类型划分,便于权限隔离) + @Bean + public String[] subscribeTopics() { + return new String[]{ + "sensor/watermaker/#", // 制水机传感器数据(TDS/水压/流量,需求图3) + "sensor/watersupply/#", // 供水机传感器数据(水位/漏水,需求图3) + "alert/#" // 设备告警报文(滤芯损坏/水位异常,需求告警流程) + }; + } + + // QoS配置(需求中告警用QoS=1确保送达,普通传感器数据QoS=0) + @Bean + public int[] qosLevels() { + return new int[]{0, 0, 1}; // 告警QoS=1,传感器数据QoS=0 + } +} \ No newline at end of file diff --git a/src/mqtt-server/MqttSubscriber.java b/src/mqtt-server/MqttSubscriber.java new file mode 100644 index 0000000..beeb56b --- /dev/null +++ b/src/mqtt-server/MqttSubscriber.java @@ -0,0 +1,73 @@ +package com.campus.water.mqtt.core; + +import com.campus.water.mqtt.service.AlertTriggerService; +import com.campus.water.mqtt.service.SensorDataStorage; +import org.eclipse.paho.client.mqttv3.IMqttMessageListener; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +/** + * MQTT数据订阅器(接收制水机/供水机数据,对应需求中“云端接收设备数据”) + */ +@Component +public class MqttSubscriber { + @Autowired + private MqttClient mqttClient; + @Autowired + private String[] subscribeTopics; + @Autowired + private int[] qosLevels; + @Autowired + private DataParser dataParser; + @Autowired + private DataForwarder dataForwarder; + @Autowired + private SensorDataStorage sensorDataStorage; + @Autowired + private AlertTriggerService alertTriggerService; + + // 初始化订阅(项目启动后自动执行) + @PostConstruct + public void startSubscribe() throws Exception { + // 为每个主题绑定消息监听器 + for (int i = 0; i < subscribeTopics.length; i++) { + String topic = subscribeTopics[i]; + int qos = qosLevels[i]; + mqttClient.subscribe(topic, qos, messageListener()); + System.out.println("MQTT服务器已订阅主题:" + topic + "(QoS=" + qos + ")"); + } + } + + // 消息监听器(接收数据后解析→存储→转发) + private IMqttMessageListener messageListener() { + return (topic, message) -> { + String payload = new String(message.getPayload()); + System.out.println("MQTT服务器接收数据:主题=" + topic + ",内容=" + payload); + + // 按主题类型处理(严格对齐需求中设备数据类型) + if (topic.startsWith("sensor/watermaker/")) { + // 1. 处理制水机传感器数据(TDS/水压/流量) + var sensorData = dataParser.parseWaterMakerData(topic, payload); + sensorDataStorage.saveToInfluxDB(sensorData); // 存入时序库 + dataForwarder.forwardToWeb(sensorData); // 转发到管理Web + dataForwarder.forwardToStudentApp(sensorData); // 转发到学生APP(水质数据) + } else if (topic.startsWith("sensor/watersupply/")) { + // 2. 处理供水机传感器数据(水位) + var sensorData = dataParser.parseWaterSupplyData(topic, payload); + sensorDataStorage.saveToInfluxDB(sensorData); // 存入时序库 + dataForwarder.forwardToWeb(sensorData); // 转发到管理Web + dataForwarder.forwardToRepairApp(sensorData); // 转发到维修APP(辖区水位) + } else if (topic.startsWith("alert/")) { + // 3. 处理告警报文(触发工单) + var alert = dataParser.parseAlertMessage(topic, payload); + alertTriggerService.createWorkOrder(alert); // 生成工单(存入MySQL) + dataForwarder.forwardToWeb(alert); // 转发到管理Web(告警列表) + dataForwarder.forwardToRepairApp(alert); // 转发到维修APP(抢单) + } + }; + } +} \ No newline at end of file diff --git a/src/repair-app/ RepairMqttSubscriber.java b/src/repair-app/ RepairMqttSubscriber.java new file mode 100644 index 0000000..fae45b3 --- /dev/null +++ b/src/repair-app/ RepairMqttSubscriber.java @@ -0,0 +1,62 @@ +package com.campus.water.repair.mqtt; + +import com.alibaba.fastjson2.JSONObject; +import com.campus.water.repair.config.RepairMqttConfig; +import com.campus.water.repair.entity.AreaDeviceVO; +import com.campus.water.repair.entity.RepairAlertVO; +import com.campus.water.repair.service.AreaDeviceService; +import com.campus.water.repair.service.WorkOrderService; +import org.eclipse.paho.client.mqttv3.IMqttMessageListener; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 维修APP端MQTT订阅器(仅接收本辖区设备数据/告警,适配“抢单/巡检”需求) + */ +@Component +public class RepairMqttSubscriber { + @Autowired + private RepairMqttConfig mqttConfig; + @Autowired + private AreaDeviceService areaDeviceService; + @Autowired + private WorkOrderService workOrderService; + + // 维修员登录后订阅本辖区数据(先查询维修员所属片区) + public void subscribeAreaData(String repairmanId, String areaId) throws Exception { + MqttClient client = mqttConfig.mqttClient(repairmanId); + + // 1. 订阅本辖区设备数据(供水机水位/制水机状态) + String deviceTopic = mqttConfig.getDeviceSubscribeTopic(areaId); + client.subscribe(deviceTopic, 0, deviceMessageListener(areaId)); + + // 2. 订阅本辖区告警报文(触发抢单) + String alertTopic = mqttConfig.getAlertSubscribeTopic(areaId); + client.subscribe(alertTopic, 1, alertMessageListener(areaId)); + + System.out.println("维修APP(ID:" + repairmanId + ")已订阅片区" + areaId + "数据"); + } + + // 设备数据监听器(缓存辖区设备状态,供巡检使用) + private IMqttMessageListener deviceMessageListener(String areaId) { + return (topic, message) -> { + String payload = new String(message.getPayload()); + AreaDeviceVO deviceVO = JSONObject.parseObject(payload, AreaDeviceVO.class); + areaDeviceService.updateAreaDeviceStatus(areaId, deviceVO); + System.out.println("维修APP接收片区" + areaId + "设备数据:" + payload); + }; + } + + // 告警监听器(新告警触发工单,推送抢单提醒) + private IMqttMessageListener alertMessageListener(String areaId) { + return (topic, message) -> { + String payload = new String(message.getPayload()); + RepairAlertVO alertVO = JSONObject.parseObject(payload, RepairAlertVO.class); + // 触发工单生成(存入MySQL)并推送抢单提醒 + workOrderService.createWorkOrderFromAlert(alertVO); + System.out.println("维修APP接收片区" + areaId + "告警:" + payload + "(已生成工单)"); + }; + } +} \ No newline at end of file diff --git a/src/repair-app/RepairMqttConfig.java b/src/repair-app/RepairMqttConfig.java new file mode 100644 index 0000000..fb67d32 --- /dev/null +++ b/src/repair-app/RepairMqttConfig.java @@ -0,0 +1,43 @@ +package com.campus.water.repair.config; + +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 维修APP端MQTT配置(仅订阅本辖区设备数据/告警,适配维修员权限需求) + */ +@Configuration +public class RepairMqttConfig { + private String mqttBroker = "tcp://mqtt-server.campus.com:1883"; + private String clientIdPrefix = "campus-water-repair-"; // 客户端ID前缀(拼接维修员ID) + + // 动态生成客户端ID(按维修员ID区分) + @Bean + public String clientId(String repairmanId) { + return clientIdPrefix + repairmanId; + } + + @Bean + public MqttClient mqttClient(String repairmanId) throws Exception { + String clientId = clientId(repairmanId); + MqttClient client = new MqttClient(mqttBroker, clientId, new MemoryPersistence()); + MqttConnectOptions options = new MqttConnectOptions(); + options.setCleanSession(false); // 重连后恢复订阅,避免错过工单 + options.setKeepAliveInterval(60); + client.connect(options); + System.out.println("维修APP(ID:" + repairmanId + ")已连接MQTT服务器"); + return client; + } + + // 订阅主题(仅本辖区设备数据+告警,适配“维修员仅查看本辖区”需求) + public String getDeviceSubscribeTopic(String areaId) { + return "forward/repair/area/" + areaId + "/device/#"; + } + + public String getAlertSubscribeTopic(String areaId) { + return "forward/repair/area/" + areaId + "/alert/#"; + } +} \ No newline at end of file diff --git a/src/repair-app/WorkOrderController.java b/src/repair-app/WorkOrderController.java new file mode 100644 index 0000000..69d31d6 --- /dev/null +++ b/src/repair-app/WorkOrderController.java @@ -0,0 +1,53 @@ +package com.campus.water.repair.controller; + +import com.campus.water.repair.entity.WorkOrderVO; +import com.campus.water.repair.service.WorkOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 工单接口(供维修APP前端调用,适配“抢单/处理工单、跟踪状态”需求) + */ +@RestController +@RequestMapping("/api/repair/workOrder") +public class WorkOrderController { + @Autowired + private WorkOrderService workOrderService; + + // 1. 获取本辖区待抢单工单(需求“抢单”功能) + @GetMapping("/pending/{repairmanId}") + public List getPendingWorkOrder(@PathVariable String repairmanId) { + String areaId = workOrderService.getRepairmanArea(repairmanId); // 获取维修员所属片区 + return workOrderService.getPendingWorkOrderByArea(areaId); + } + + // 2. 抢单(需求核心功能,需校验辖区权限) + @PostMapping("/grab") + public String grabWorkOrder( + @RequestParam String repairmanId, + @RequestParam String orderId + ) { + return workOrderService.grabWorkOrder(repairmanId, orderId) ? + "抢单成功,请及时处理" : "工单已被抢,或您无权限抢此工单"; + } + + // 3. 提交工单处理结果(需求“处理工单并提交”功能) + @PostMapping("/complete") + public String completeWorkOrder( + @RequestParam String orderId, + @RequestParam String repairmanId, + @RequestParam String dealNote, // 处理备注(如“已更换滤芯”) + @RequestParam String imgUrl // 现场照片URL(可选) + ) { + workOrderService.completeWorkOrder(orderId, repairmanId, dealNote, imgUrl); + return "工单处理完成,已提交审核"; + } + + // 4. 查看个人处理中的工单(需求“跟踪工单状态”功能) + @GetMapping("/processing/{repairmanId}") + public List getProcessingWorkOrder(@PathVariable String repairmanId) { + return workOrderService.getProcessingWorkOrderByRepairman(repairmanId); + } +} \ No newline at end of file diff --git a/src/student-app/ StudentMqttConfig.java b/src/student-app/ StudentMqttConfig.java new file mode 100644 index 0000000..72d5b88 --- /dev/null +++ b/src/student-app/ StudentMqttConfig.java @@ -0,0 +1,39 @@ +package com.campus.water.student.config; + +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 学生APP端MQTT配置(仅订阅终端机水质数据,适配学生权限需求) + */ +@Configuration +public class StudentMqttConfig { + private String mqttBroker = "tcp://mqtt-server.campus.com:1883"; + private String clientIdPrefix = "campus-water-student-"; // 客户端ID前缀(拼接学生ID) + + // 动态生成客户端ID(按学生ID区分,避免冲突) + @Bean + public String clientId(String studentId) { + return clientIdPrefix + studentId; + } + + @Bean + public MqttClient mqttClient(String studentId) throws Exception { + String clientId = clientId(studentId); + MqttClient client = new MqttClient(mqttBroker, clientId, new MemoryPersistence()); + MqttConnectOptions options = new MqttConnectOptions(); + options.setCleanSession(true); // 学生APP登录后重新订阅,无需保留会话 + options.setKeepAliveInterval(120); // 移动端心跳间隔 longer,适配电池续航 + client.connect(options); + System.out.println("学生APP(ID:" + studentId + ")已连接MQTT服务器"); + return client; + } + + // 订阅主题(仅终端机水质数据,适配学生“扫码查水质”需求) + public String getSubscribeTopic(String terminalId) { + return "forward/student/terminal/" + terminalId; + } +} \ No newline at end of file diff --git a/src/student-app/DrinkController.java b/src/student-app/DrinkController.java new file mode 100644 index 0000000..64708e8 --- /dev/null +++ b/src/student-app/DrinkController.java @@ -0,0 +1,49 @@ +package com.campus.water.student.controller; + +import com.campus.water.student.entity.DrinkRecordVO; +import com.campus.water.student.service.DrinkRecordService; +import com.campus.water.student.service.WaterQualityService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +/** + * 饮水接口(供学生APP前端调用,适配“扫码用水、查看饮水量”需求) + */ +@RestController +@RequestMapping("/api/student/drink") +public class DrinkController { + @Autowired + private DrinkRecordService drinkRecordService; + @Autowired + private WaterQualityService waterQualityService; + + // 1. 扫码用水(生成饮水记录,需求核心功能) + @PostMapping("/scan") + public String scanDrink( + @RequestParam String studentId, + @RequestParam String terminalId, + @RequestParam double volume // 饮水量(终端机流量传感器获取或按时间估算) + ) { + // 获取当前终端机水质(用于记录) + String waterQuality = waterQualityService.getWaterQuality(terminalId); + // 生成饮水记录(存入MySQL) + drinkRecordService.createDrinkRecord(studentId, terminalId, volume, waterQuality); + return "扫码用水成功,饮水量:" + volume + "L,水质:" + waterQuality; + } + + // 2. 查询今日饮水量(需求“查看每日饮水量”功能) + @GetMapping("/today/{studentId}") + public DrinkRecordVO getTodayDrink(@PathVariable String studentId) { + return drinkRecordService.getTodayDrinkRecord(studentId); + } + + // 3. 查询历史饮水量(按日/周/月筛选) + @GetMapping("/history/{studentId}") + public List getHistoryDrink( + @PathVariable String studentId, + @RequestParam String type, // type: day/week/month + @RequestParam String date // 日期(如2024-05-20) + ) { + return drinkRecordService.getHistoryDrinkRecord(studentId, type, date); + } +} \ No newline at end of file diff --git a/src/student-app/StudentMqttSubscriber.java b/src/student-app/StudentMqttSubscriber.java new file mode 100644 index 0000000..943a6c3 --- /dev/null +++ b/src/student-app/StudentMqttSubscriber.java @@ -0,0 +1,45 @@ +package com.campus.water.student.mqtt; + +import com.alibaba.fastjson2.JSONObject; +import com.campus.water.student.config.StudentMqttConfig; +import com.campus.water.student.entity.WaterQualityVO; +import com.campus.water.student.service.WaterQualityService; +import org.eclipse.paho.client.mqttv3.IMqttMessageListener; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 学生APP端MQTT订阅器(仅接收终端机水质数据,适配“扫码查水质”需求) + */ +@Component +public class StudentMqttSubscriber { + @Autowired + private StudentMqttConfig mqttConfig; + @Autowired + private WaterQualityService waterQualityService; + + // 学生扫码后订阅对应终端机的水质数据 + public void subscribeTerminalWaterQuality(String studentId, String terminalId) throws Exception { + // 1. 创建MQTT客户端(按学生ID区分) + MqttClient client = mqttConfig.mqttClient(studentId); + + // 2. 订阅该终端机的水质主题 + String topic = mqttConfig.getSubscribeTopic(terminalId); + client.subscribe(topic, 0, messageListener(terminalId)); + System.out.println("学生APP(ID:" + studentId + ")已订阅终端机" + terminalId + "水质数据"); + } + + // 消息监听器(缓存水质数据,供APP前端展示) + private IMqttMessageListener messageListener(String terminalId) { + return (topic, message) -> { + String payload = new String(message.getPayload()); + System.out.println("学生APP接收终端机" + terminalId + "水质数据:" + payload); + + // 解析水质数据并缓存 + WaterQualityVO qualityVO = JSONObject.parseObject(payload, WaterQualityVO.class); + waterQualityService.updateWaterQuality(terminalId, qualityVO); + }; + } +} \ No newline at end of file From fa98dacdb8bceb1f17cdc0993ad2b433cbdc38f2 Mon Sep 17 00:00:00 2001 From: luoyuehang <2830398107@qq.com> Date: Sun, 19 Oct 2025 17:02:57 +0800 Subject: [PATCH 06/12] =?UTF-8?q?=E7=BD=97=E6=9C=88=E8=88=AA4=E5=91=A8?= =?UTF-8?q?=E6=80=BB=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../members/luoyuehang-weekly-summary-04.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 doc/process/weekly/week-4/members/luoyuehang-weekly-summary-04.md diff --git a/doc/process/weekly/week-4/members/luoyuehang-weekly-summary-04.md b/doc/process/weekly/week-4/members/luoyuehang-weekly-summary-04.md new file mode 100644 index 0000000..97ce817 --- /dev/null +++ b/doc/process/weekly/week-4/members/luoyuehang-weekly-summary-04.md @@ -0,0 +1,33 @@ + +# 个人周总结-第4周 + +## 姓名和起止时间 + +**姓  名:** [罗月航] +**团队名称:** 1班-汪汪队 +**开始时间:** 2025-10-13 +**结束时间:** 2025-10-19 + +## 本周任务完成情况 + +| 序号 | 总结内容 | 是否完成 | 情况说明 | +| ---- | -------- | -------- | -------- | +| 1 | 需求分析与理解 | 完成 | 仔细研读了项目需求文档,明确了管理员、维修人员、学生三类用户的功能需求和业务流程 | +| 2 | 设计规范制定 | 完成 | 与协作者共同确定了Web端与移动端统一的设计风格、色彩体系和基础组件规范 | +| 3 | 维修人员APP原型设计 | 基本完成 | 完成了维修人员APP核心页面(设备监控、工单列表、抢单处理流程)的线框图设计 | +| 4 | 管理员平台协作设计 | 部分完成 | 协助完成了管理员平台"工单跟踪"模块的初步界面设计 | +| 5 | 设计评审与优化 | 完成 | 参与了内部设计评审会议,根据反馈意见对维修人员APP原型进行了初步优化 | + +## 对团队工作的建议 + +1. **设计协作:** 建议建立团队共享的设计资源库,统一图标、组件等设计元素; +2. **沟通机制:** 建议固定每日站会时间,及时同步设计进展和遇到的问题; +3. **技术预研:** 建议前端开发提前了解接口数据结构,确保设计与开发衔接顺畅。 + +## 小结 + +1. **设计产出:** 完成了维修人员APP的主体原型设计,确立了项目整体的视觉风格; +2. **协作成效:** 与协作者配合良好,保持了Web端与移动端设计风格的一致性; +3. **技能提升:** 通过实际项目实践,提升了移动端界面设计的专业能力; +4. **后续计划:** 根据评审反馈完善设计细节,并开始准备前端开发环境搭建。 + From f71f2b4fac73a40aa9ace4191899b19ac3e29168 Mon Sep 17 00:00:00 2001 From: wanglei <3085637232@qq.com> Date: Sun, 19 Oct 2025 18:01:18 +0800 Subject: [PATCH 07/12] =?UTF-8?q?=E7=8E=8B=E7=A3=8A=E7=AC=AC=E5=9B=9B?= =?UTF-8?q?=E5=91=A8=E5=AE=8C=E6=88=90=E7=9A=84=E4=BB=BB=E5=8A=A1-?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E7=8E=B0=E5=B7=B2=E5=AE=9E=E7=8E=B0=E4=BB=8E?= =?UTF-8?q?MQTT=E6=95=B0=E6=8D=AE=E6=8E=A5=E6=94=B6=E3=80=81=E6=99=BA?= =?UTF-8?q?=E8=83=BD=E8=A7=A3=E6=9E=90=E3=80=81=E8=87=AA=E5=8A=A8=E5=91=8A?= =?UTF-8?q?=E8=AD=A6=E5=88=B0MySQL=E6=95=B0=E6=8D=AE=E5=BA=93=E5=AD=98?= =?UTF-8?q?=E5=82=A8=E7=9A=84=E5=AE=8C=E6=95=B4=E6=95=B0=E6=8D=AE=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=B5=81=E6=B0=B4=E7=BA=BF=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=A4=9A=E7=AB=AF=E6=95=B0=E6=8D=AE=E5=88=86=E5=8F=91=E5=92=8C?= =?UTF-8?q?=E5=AE=9E=E6=97=B6=E7=9B=91=E6=8E=A7=E5=91=8A=E8=AD=A6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../members/wanglei-weekly-summary-04.md | 39 +++++ src/manage-web/MonitorController.java | 19 +-- src/manage-web/RealTimeService.java | 30 ++++ src/manage-web/WebMqttConfig.java | 16 +- src/manage-web/WebMqttSubscriber.java | 16 +- src/mqtt-server/DataForwarder.java | 76 +++++----- src/mqtt-server/MqttConfig.java | 30 ++-- src/mqtt-server/MqttSubscriber.java | 137 +++++++++++++----- 8 files changed, 237 insertions(+), 126 deletions(-) create mode 100644 doc/process/weekly/week-4/members/wanglei-weekly-summary-04.md create mode 100644 src/manage-web/RealTimeService.java diff --git a/doc/process/weekly/week-4/members/wanglei-weekly-summary-04.md b/doc/process/weekly/week-4/members/wanglei-weekly-summary-04.md new file mode 100644 index 0000000..b94bfe3 --- /dev/null +++ b/doc/process/weekly/week-4/members/wanglei-weekly-summary-04.md @@ -0,0 +1,39 @@ + +# 个人周总结-第4周 + +## 姓名和起止时间 + +**姓  名:** 王磊 +**团队名称:** 1班-汪汪队 +**开始时间:** 2025-10-13 +**结束时间:** 2025-10-19 + +## 本周任务完成情况 + +序号 总结内容 是否完成 情况说明 +1 MySQL数据库环境搭建与配置 完成 成功安装MySQL 8.0.43,创建water_management数据库,配置数据库连接环境变量,解决数据库连接权限问题 +2 MQTT数据处理器开发 完成 实现基于Java的MQTT数据接收、解析和处理模块,支持制水机和供水机两种设备类型的数据处理 +3 数据库表结构设计与创建 完成 设计并创建device_data设备数据表和device_alert告警表,建立完整的数据存储结构 +4 数据解析与业务逻辑实现 完成 实现JSON数据解析、设备状态判断、异常检测和自动告警生成功能 +5 项目集成与测试 完成 成功将数据处理模块集成到智慧饮水系统项目中,完成多组测试数据的验证 + +## 对团队工作的建议 + +1. **互助学习:** 小组成员应该根据自身的技能长短开展互帮互助的活动,共同努力提高小组成员的专业水平; +2. **进度统一:** 团队成员尽量统一项目进度; + +## 小结 + + +1. **技能学习:** 小组成员各自开展自己所负责部分的个人技能的学习; +2. **项目管理:** PM及时推进项目进度,确保工作有条不紊; +3. **计划制定:** 根据本周任务完成情况与下一阶段文档提交要求,制定团队任务计划。 + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. 所有组员都需提交个人周计划、周总结文档,上传至代码托管平台; \ No newline at end of file diff --git a/src/manage-web/MonitorController.java b/src/manage-web/MonitorController.java index 441d1f5..9f82f30 100644 --- a/src/manage-web/MonitorController.java +++ b/src/manage-web/MonitorController.java @@ -1,16 +1,10 @@ package com.campus.water.web.controller; -import com.campus.water.web.entity.SensorDataWebVO; -import com.campus.water.web.service.RealTimeService; -import com.campus.water.web.service.HistoryDataService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; -/** - * 监控数据接口(供Web前端Vue调用,适配管理员“监控设备数据”需求) - */ @RestController @RequestMapping("/api/admin/monitor") public class MonitorController { @@ -19,24 +13,21 @@ public class MonitorController { @Autowired private HistoryDataService historyDataService; - // 1. 获取单设备实时数据(适配前端设备详情页) @GetMapping("/realTime/{deviceId}") - public SensorDataWebVO getRealTimeData(@PathVariable String deviceId) { + public Object getRealTimeData(@PathVariable String deviceId) { return realTimeService.getRealTimeData(deviceId); } - // 2. 获取全量设备实时状态(适配前端监控总览页) @GetMapping("/realTime/all") - public List getAllRealTimeData() { + public List getAllRealTimeData() { return realTimeService.getAllRealTimeData(); } - // 3. 获取设备历史数据(适配前端历史曲线,需求中“查看历史水质”) @GetMapping("/history/{deviceId}") - public List getHistoryData( + public List getHistoryData( @PathVariable String deviceId, - @RequestParam String startTime, // 开始时间(如2024-05-20 00:00:00) - @RequestParam String endTime // 结束时间 + @RequestParam String startTime, + @RequestParam String endTime ) { return historyDataService.getHistoryData(deviceId, startTime, endTime); } diff --git a/src/manage-web/RealTimeService.java b/src/manage-web/RealTimeService.java new file mode 100644 index 0000000..5ee933e --- /dev/null +++ b/src/manage-web/RealTimeService.java @@ -0,0 +1,30 @@ +package com.campus.water.web; + +import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +@Service +public class RealTimeService { + + private ConcurrentHashMap realTimeData = new ConcurrentHashMap<>(); + private List alerts = new ArrayList<>(); + + public void updateRealTimeData(Object sensorData) { + System.out.println("更新实时数据"); + } + + public void addAlert(Object alertData) { + alerts.add(alertData); + System.out.println("添加告警"); + } + + public Object getRealTimeData(String deviceId) { + return realTimeData.get(deviceId); + } + + public List getAllRealTimeData() { + return new ArrayList<>(realTimeData.values()); + } +} \ No newline at end of file diff --git a/src/manage-web/WebMqttConfig.java b/src/manage-web/WebMqttConfig.java index 404c953..4f4670c 100644 --- a/src/manage-web/WebMqttConfig.java +++ b/src/manage-web/WebMqttConfig.java @@ -6,14 +6,11 @@ import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -/** - * 管理Web端MQTT配置(订阅MQTT服务器转发的全量数据,适配管理员监控需求) - */ @Configuration public class WebMqttConfig { - // MQTT服务器转发的主题前缀(需求中全量设备数据/告警) - private String mqttBroker = "tcp://mqtt-server.campus.com:1883"; - private String clientId = "campus-water-admin-web"; // Web端客户端ID + // 修改为本地MQTT + private String mqttBroker = "tcp://localhost:1883"; + private String clientId = "campus-water-admin-web"; @Bean public MqttClient mqttClient() throws Exception { @@ -26,17 +23,16 @@ public class WebMqttConfig { return client; } - // 订阅的主题(全量设备数据+全量告警,适配管理员权限) @Bean public String[] subscribeTopics() { return new String[]{ - "forward/web/device/#", // 全量设备实时数据 - "forward/web/alert/#" // 全量告警报文 + "forward/web/device/#", + "forward/web/alert/#" }; } @Bean public int[] qosLevels() { - return new int[]{0, 1}; // 告警QoS=1,设备数据QoS=0 + return new int[]{0, 1}; } } \ No newline at end of file diff --git a/src/manage-web/WebMqttSubscriber.java b/src/manage-web/WebMqttSubscriber.java index 3881249..604501f 100644 --- a/src/manage-web/WebMqttSubscriber.java +++ b/src/manage-web/WebMqttSubscriber.java @@ -1,9 +1,6 @@ package com.campus.water.web.mqtt; import com.alibaba.fastjson2.JSONObject; -import com.campus.water.web.entity.SensorDataWebVO; -import com.campus.water.web.entity.AlertWebVO; -import com.campus.water.web.service.RealTimeService; import org.eclipse.paho.client.mqttv3.IMqttMessageListener; import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttMessage; @@ -12,9 +9,6 @@ import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; -/** - * 管理Web端MQTT订阅器(接收实时设备数据/告警,适配管理员监控需求) - */ @Component public class WebMqttSubscriber { @Autowired @@ -41,13 +35,13 @@ public class WebMqttSubscriber { String payload = new String(message.getPayload()); System.out.println("管理Web接收数据:主题=" + topic + ",内容=" + payload); - // 解析数据并缓存到内存(供前端轮询获取实时数据) + // 直接使用JSONObject处理数据 + JSONObject data = JSONObject.parseObject(payload); + if (topic.startsWith("forward/web/device/")) { - SensorDataWebVO sensorVO = JSONObject.parseObject(payload, SensorDataWebVO.class); - realTimeService.updateRealTimeData(sensorVO); // 缓存实时数据 + realTimeService.updateRealTimeData(data); } else if (topic.startsWith("forward/web/alert/")) { - AlertWebVO alertVO = JSONObject.parseObject(payload, AlertWebVO.class); - realTimeService.addAlert(alertVO); // 缓存告警(前端告警列表实时更新) + realTimeService.addAlert(data); } }; } diff --git a/src/mqtt-server/DataForwarder.java b/src/mqtt-server/DataForwarder.java index bbd4dcf..99a2123 100644 --- a/src/mqtt-server/DataForwarder.java +++ b/src/mqtt-server/DataForwarder.java @@ -1,83 +1,83 @@ package com.campus.water.mqtt.core; import com.alibaba.fastjson2.JSONObject; -import com.campus.water.mqtt.entity.SensorData; -import com.campus.water.mqtt.entity.AlertMessage; import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttMessage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -/** - * 数据转发器(按需求转发到管理Web/学生APP/维修APP,实现多端数据同步) - */ +import java.util.Map; + @Component public class DataForwarder { @Autowired private MqttClient mqttClient; - // 1. 转发传感器数据到管理Web(全量数据,适配管理员监控需求) - public void forwardToWeb(SensorData sensorData) throws Exception { - String topic = "forward/web/device/" + sensorData.getDeviceId(); + public void forwardToWeb(Map sensorData) throws Exception { + String deviceId = (String) sensorData.get("deviceId"); + String topic = "forward/web/device/" + deviceId; String payload = JSONObject.toJSONString(sensorData); - publish(topic, payload, 0); // Web端QoS=0(普通监控数据) + publish(topic, payload, 0); + System.out.println("转发到管理Web: " + deviceId); } - // 2. 转发告警到管理Web(适配管理员查看告警需求) - public void forwardToWeb(AlertMessage alert) throws Exception { - String topic = "forward/web/alert/" + alert.getDeviceId(); - String payload = JSONObject.toJSONString(alert); - publish(topic, payload, 1); // 告警QoS=1(确保管理员看到) + public void forwardToWeb(Map alertData, boolean isAlert) throws Exception { + String deviceId = (String) alertData.get("deviceId"); + String topic = "forward/web/alert/" + deviceId; + String payload = JSONObject.toJSONString(alertData); + publish(topic, payload, 1); + System.out.println("转发告警到管理Web: " + deviceId); } - // 3. 转发制水机水质数据到学生APP(仅终端机关联的制水机,适配查水质需求) - public void forwardToStudentApp(SensorData sensorData) throws Exception { - // 仅制水机数据需转发(学生APP查水质) - if (sensorData.getDeviceType() != 1) return; + public void forwardToStudentApp(Map sensorData) throws Exception { + Integer deviceType = (Integer) sensorData.get("deviceType"); + if (deviceType != 1) return; - // 按终端机ID转发(需求中学生扫码查对应终端机的水质) - String terminalId = getRelatedTerminalId(sensorData.getDeviceId()); + String deviceId = (String) sensorData.get("deviceId"); + String terminalId = getRelatedTerminalId(deviceId); String topic = "forward/student/terminal/" + terminalId; + + Double tdsValue = (Double) sensorData.get("tdsValue"); String payload = JSONObject.toJSONString(new JSONObject() {{ put("terminalId", terminalId); - put("tdsValue", sensorData.getTdsValue()); - put("waterQuality", getWaterQuality(sensorData.getTdsValue())); // 水质等级 - put("timestamp", sensorData.getTimestamp()); + put("tdsValue", tdsValue); + put("waterQuality", getWaterQuality(tdsValue)); + put("timestamp", sensorData.get("timestamp")); }}); publish(topic, payload, 0); + System.out.println("转发到学生APP: " + terminalId); } - // 4. 转发供水机水位/告警到维修APP(仅本辖区设备,适配维修员权限需求) - public void forwardToRepairApp(SensorData sensorData) throws Exception { - String areaId = sensorData.getAreaId(); // 设备所属片区(如AREA01) - String topic = "forward/repair/area/" + areaId + "/device/" + sensorData.getDeviceId(); + public void forwardToRepairApp(Map sensorData) throws Exception { + String areaId = (String) sensorData.get("areaId"); + String deviceId = (String) sensorData.get("deviceId"); + String topic = "forward/repair/area/" + areaId + "/device/" + deviceId; String payload = JSONObject.toJSONString(sensorData); publish(topic, payload, 0); + System.out.println("转发到维修APP: " + deviceId); } - public void forwardToRepairApp(AlertMessage alert) throws Exception { - String areaId = alert.getAreaId(); - String topic = "forward/repair/area/" + areaId + "/alert/" + alert.getDeviceId(); - String payload = JSONObject.toJSONString(alert); - publish(topic, payload, 1); // 告警QoS=1(确保维修员抢单) + public void forwardToRepairApp(Map alertData, boolean isAlert) throws Exception { + String areaId = (String) alertData.get("areaId"); + String deviceId = (String) alertData.get("deviceId"); + String topic = "forward/repair/area/" + areaId + "/alert/" + deviceId; + String payload = JSONObject.toJSONString(alertData); + publish(topic, payload, 1); + System.out.println("转发告警到维修APP: " + deviceId); } - // 通用发布方法 private void publish(String topic, String payload, int qos) throws Exception { MqttMessage message = new MqttMessage(payload.getBytes()); message.setQos(qos); mqttClient.publish(topic, message); - System.out.println("MQTT服务器转发数据:主题=" + topic + ",内容=" + payload); } - // 工具方法:根据制水机ID获取关联的终端机ID(需求中终端机关联制水机) private String getRelatedTerminalId(String deviceId) { - // 实际需从MySQL设备表查询,此处模拟(如制水机WM001关联终端机TERM001/TERM002) return deviceId.equals("WM001") ? "TERM001" : "TERM002"; } - // 工具方法:根据TDS值判断水质等级(需求中“优质矿化水”标准) - private String getWaterQuality(double tds) { + private String getWaterQuality(Double tds) { + if (tds == null) return "未知"; if (tds < 50) return "纯净水(无矿物质)"; else if (tds < 300) return "优质矿化水"; else if (tds < 600) return "合格矿化水"; diff --git a/src/mqtt-server/MqttConfig.java b/src/mqtt-server/MqttConfig.java index 0f060f6..6d0c562 100644 --- a/src/mqtt-server/MqttConfig.java +++ b/src/mqtt-server/MqttConfig.java @@ -6,48 +6,38 @@ import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.util.Properties; - -/** - * MQTT服务器配置(适配需求中Air724模块数据上传,对接MQTT Broker) - */ @Configuration public class MqttConfig { - // 从配置文件读取Broker地址(需求中云端Broker,如EMQX) - private String brokerUrl = "tcp://mqtt-server.campus.com:1883"; - private String clientId = "campus-water-mqtt-server"; // 服务器端客户端ID - private int keepAlive = 60; // 心跳间隔(秒),适配Air724模块低功耗 + // 修改为本地MQTT broker + private String brokerUrl = "tcp://localhost:1883"; + private String clientId = "campus-water-mqtt-server"; + private int keepAlive = 60; @Bean public MqttClient mqttClient() throws Exception { - // 1. 创建MQTT客户端(内存持久化,避免服务器存储压力) MqttClient client = new MqttClient(brokerUrl, clientId, new MemoryPersistence()); - // 2. 配置连接参数(确保数据可靠传输,适配需求中告警不丢失) MqttConnectOptions options = new MqttConnectOptions(); - options.setCleanSession(false); // 保持会话,重连后恢复订阅 + options.setCleanSession(false); options.setKeepAliveInterval(keepAlive); - options.setAutomaticReconnect(true); // 自动重连,适配网络波动 + options.setAutomaticReconnect(true); - // 3. 连接Broker client.connect(options); System.out.println("MQTT服务器已连接Broker:" + brokerUrl); return client; } - // 订阅的主题(严格按需求中设备类型划分,便于权限隔离) @Bean public String[] subscribeTopics() { return new String[]{ - "sensor/watermaker/#", // 制水机传感器数据(TDS/水压/流量,需求图3) - "sensor/watersupply/#", // 供水机传感器数据(水位/漏水,需求图3) - "alert/#" // 设备告警报文(滤芯损坏/水位异常,需求告警流程) + "sensor/watermaker/#", + "sensor/watersupply/#", + "alert/#" }; } - // QoS配置(需求中告警用QoS=1确保送达,普通传感器数据QoS=0) @Bean public int[] qosLevels() { - return new int[]{0, 0, 1}; // 告警QoS=1,传感器数据QoS=0 + return new int[]{0, 0, 1}; } } \ No newline at end of file diff --git a/src/mqtt-server/MqttSubscriber.java b/src/mqtt-server/MqttSubscriber.java index beeb56b..3f83755 100644 --- a/src/mqtt-server/MqttSubscriber.java +++ b/src/mqtt-server/MqttSubscriber.java @@ -1,7 +1,6 @@ package com.campus.water.mqtt.core; -import com.campus.water.mqtt.service.AlertTriggerService; -import com.campus.water.mqtt.service.SensorDataStorage; +import com.alibaba.fastjson2.JSONObject; import org.eclipse.paho.client.mqttv3.IMqttMessageListener; import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttMessage; @@ -9,10 +8,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; -/** - * MQTT数据订阅器(接收制水机/供水机数据,对应需求中“云端接收设备数据”) - */ @Component public class MqttSubscriber { @Autowired @@ -22,18 +21,10 @@ public class MqttSubscriber { @Autowired private int[] qosLevels; @Autowired - private DataParser dataParser; - @Autowired private DataForwarder dataForwarder; - @Autowired - private SensorDataStorage sensorDataStorage; - @Autowired - private AlertTriggerService alertTriggerService; - // 初始化订阅(项目启动后自动执行) @PostConstruct public void startSubscribe() throws Exception { - // 为每个主题绑定消息监听器 for (int i = 0; i < subscribeTopics.length; i++) { String topic = subscribeTopics[i]; int qos = qosLevels[i]; @@ -42,32 +33,112 @@ public class MqttSubscriber { } } - // 消息监听器(接收数据后解析→存储→转发) private IMqttMessageListener messageListener() { return (topic, message) -> { String payload = new String(message.getPayload()); System.out.println("MQTT服务器接收数据:主题=" + topic + ",内容=" + payload); - // 按主题类型处理(严格对齐需求中设备数据类型) - if (topic.startsWith("sensor/watermaker/")) { - // 1. 处理制水机传感器数据(TDS/水压/流量) - var sensorData = dataParser.parseWaterMakerData(topic, payload); - sensorDataStorage.saveToInfluxDB(sensorData); // 存入时序库 - dataForwarder.forwardToWeb(sensorData); // 转发到管理Web - dataForwarder.forwardToStudentApp(sensorData); // 转发到学生APP(水质数据) - } else if (topic.startsWith("sensor/watersupply/")) { - // 2. 处理供水机传感器数据(水位) - var sensorData = dataParser.parseWaterSupplyData(topic, payload); - sensorDataStorage.saveToInfluxDB(sensorData); // 存入时序库 - dataForwarder.forwardToWeb(sensorData); // 转发到管理Web - dataForwarder.forwardToRepairApp(sensorData); // 转发到维修APP(辖区水位) - } else if (topic.startsWith("alert/")) { - // 3. 处理告警报文(触发工单) - var alert = dataParser.parseAlertMessage(topic, payload); - alertTriggerService.createWorkOrder(alert); // 生成工单(存入MySQL) - dataForwarder.forwardToWeb(alert); // 转发到管理Web(告警列表) - dataForwarder.forwardToRepairApp(alert); // 转发到维修APP(抢单) + try { + if (topic.startsWith("sensor/watermaker/")) { + // 解析制水机数据 + Map sensorData = parseWaterMakerData(topic, payload); + dataForwarder.forwardToWeb(sensorData); + dataForwarder.forwardToStudentApp(sensorData); + + } else if (topic.startsWith("sensor/watersupply/")) { + // 解析供水机数据 + Map sensorData = parseWaterSupplyData(topic, payload); + dataForwarder.forwardToWeb(sensorData); + dataForwarder.forwardToRepairApp(sensorData); + + } else if (topic.startsWith("alert/")) { + // 解析告警数据 + Map alertData = parseAlertMessage(topic, payload); + dataForwarder.forwardToWeb(alertData); + dataForwarder.forwardToRepairApp(alertData); + } + } catch (Exception e) { + System.err.println("处理MQTT消息异常: " + e.getMessage()); + e.printStackTrace(); } }; } + + private Map parseWaterMakerData(String topic, String payload) { + Map data = new HashMap<>(); + parseCommonData(topic, payload, data); + data.put("deviceType", 1); // 制水机 + + JSONObject json = JSONObject.parseObject(payload); + data.put("tdsValue", json.getDouble("tds")); + data.put("waterFlow", json.getDouble("flow")); + data.put("waterPressure", json.getDouble("pressure")); + data.put("filterLife", json.getInteger("filter_life")); + data.put("leakage", json.getBoolean("leakage")); + + data.put("status", determineStatus(data)); + return data; + } + + private Map parseWaterSupplyData(String topic, String payload) { + Map data = new HashMap<>(); + parseCommonData(topic, payload, data); + data.put("deviceType", 2); // 供水机 + + JSONObject json = JSONObject.parseObject(payload); + data.put("waterFlow", json.getDouble("flow")); + data.put("waterPressure", json.getDouble("pressure")); + data.put("waterLevel", json.getDouble("water_level")); + + data.put("status", determineStatus(data)); + return data; + } + + private Map parseAlertMessage(String topic, String payload) { + Map alert = new HashMap<>(); + + String[] parts = topic.split("/"); + alert.put("deviceId", parts.length >= 2 ? parts[1] : "unknown"); + + JSONObject json = JSONObject.parseObject(payload); + alert.put("alertType", json.getString("alert_type")); + alert.put("alertLevel", json.getString("alert_level")); + alert.put("alertMessage", json.getString("alert_message")); + alert.put("areaId", json.getString("area_id")); + alert.put("deviceType", json.getInteger("device_type")); + alert.put("timestamp", LocalDateTime.now().toString()); + + return alert; + } + + private void parseCommonData(String topic, String payload, Map data) { + String[] parts = topic.split("/"); + data.put("deviceId", parts.length >= 3 ? parts[2] : "unknown"); + + JSONObject json = JSONObject.parseObject(payload); + data.put("areaId", json.getString("area_id")); + data.put("temperature", json.getDouble("temperature")); + data.put("humidity", json.getDouble("humidity")); + data.put("timestamp", LocalDateTime.now().toString()); + } + + private String determineStatus(Map data) { + Integer deviceType = (Integer) data.get("deviceType"); + + if (deviceType == 1) { // 制水机 + Double tdsValue = (Double) data.get("tdsValue"); + Integer filterLife = (Integer) data.get("filterLife"); + Boolean leakage = (Boolean) data.get("leakage"); + + if (tdsValue != null && tdsValue > 600) return "error"; + if (filterLife != null && filterLife < 10) return "error"; + if (leakage != null && leakage) return "error"; + if (tdsValue != null && tdsValue > 300) return "warning"; + } else if (deviceType == 2) { // 供水机 + Double waterLevel = (Double) data.get("waterLevel"); + if (waterLevel != null && waterLevel < 10) return "error"; + if (waterLevel != null && waterLevel < 20) return "warning"; + } + return "normal"; + } } \ No newline at end of file From 94c01ada4c06810ae657b9306854d6e7de432d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E7=AB=9E=E7=94=B1?= <1193626695@qq.com> Date: Sun, 19 Oct 2025 19:00:15 +0800 Subject: [PATCH 08/12] =?UTF-8?q?=E5=91=A8=E7=AB=9E=E7=94=B1=E7=9A=84?= =?UTF-8?q?=E7=AC=AC=E5=9B=9B=E5=91=A8=E5=91=A8=E6=80=BB=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../members/zhoujingyou-weekly-plan-4.md | 2 +- .../members/zhoujingyou-weekly-summary-04.md | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 doc/process/weekly/week-4/members/zhoujingyou-weekly-summary-04.md diff --git a/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md b/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md index 64cba72..974231d 100644 --- a/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md +++ b/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md @@ -1,4 +1,4 @@ -# 个人周计划-第1周 +# 个人周计划-第4周 ## 姓名和起止时间 diff --git a/doc/process/weekly/week-4/members/zhoujingyou-weekly-summary-04.md b/doc/process/weekly/week-4/members/zhoujingyou-weekly-summary-04.md new file mode 100644 index 0000000..cbbdd2c --- /dev/null +++ b/doc/process/weekly/week-4/members/zhoujingyou-weekly-summary-04.md @@ -0,0 +1,31 @@ +# 个人周总结-第4周 + +## 姓名和起止时间 + +**姓  名:** 周竞由 +**团队名称:** 软1-汪汪队 +**开始时间:** 2025-10-13 +**结束时间:** 2025-10-19 + +## 本周任务完成情况 + +| 序号 | 总结内容 | 是否完成 | 情况说明 | +|----|--------------------------------|------|------------------------------------------------| +| 1 | 分析需求文档并与团队沟通,明确前端设计的核心功能模块 | 完成 | 已深入阅读项目需求文档,明确了学生端APP的主要功能与设计方向,并与团队讨论确认前端开发重点 | +| 2 | 制定UI设计方案,规划学生端、维修人员端和Web端的界面风格 | 完成 | 明确了整体设计风格为简洁清新风,确定主色调为蓝白系,规划了主要功能模块的布局与交互方式 | +| 3 | 完成首页和功能模块的初步UI设计,关注色彩、字体和布局 | 基本完成 | 已完成首页与部分核心功能页面的UI设计初稿,关注了可读性与层次感,并进行初步评审 | +| 4 | 继续完善学生端APP的UI设计,加入动画效果和交互细节 | 部分完成 | 已设计部分交互细节与动画效果,收集团队反馈后计划下周进一步优化体验 | +| 5 | 开始前端页面布局开发,使用HTML & CSS编写基本结构 | 进行中 | 已搭建学生端基础页面框架,正在完善响应式布局与后端接口对接测试 | + +## 对团队工作的建议 + +1. **接口文档提前共享:** 建议后端开发尽早提供学生端接口数据结构说明,以便前端更高效地完成数据对接; +2. **设计风格统一:** 建议团队建立统一的UI组件库或样式规范,确保多端界面一致性; +3. **阶段评审机制:** 每周可定期进行一次UI评审或开发同步会,促进协作效率。 + +## 小结 + +1. **设计成果:** 本周完成了学生端整体UI设计方案,初步确定了APP界面布局与色彩风格; +2. **开发进展:** 完成了首页与部分页面的前端结构搭建,为后续功能开发奠定基础; +3. **学习提升:** 在本周过程中加强了对HTML、CSS布局及UI交互设计的掌握; +4. **后续计划:** 下周将重点完善交互动画与页面细节,实现接口数据对接与动态展示功能。 From 1ba72ffe5f9626da73ec30c1ebc456e759b1cb85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E7=AB=9E=E7=94=B1?= <1193626695@qq.com> Date: Sun, 19 Oct 2025 19:02:08 +0800 Subject: [PATCH 09/12] =?UTF-8?q?=E5=91=A8=E7=AB=9E=E7=94=B1=E7=9A=84?= =?UTF-8?q?=E7=AC=AC=E5=9B=9B=E5=91=A8=E5=91=A8=E6=80=BB=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md | 2 +- .../weekly/week-4/members/zhoujingyou-weekly-summary-04.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md b/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md index 974231d..65ae73c 100644 --- a/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md +++ b/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md @@ -4,7 +4,7 @@ **姓  名:** 周竞由 **团队名称:** 软1-汪汪队 -**开始时间:** 2025-10-13 +**开始时间:** 2025-10-13 **结束时间:** 2025-10-19 ## 本周任务计划安排 diff --git a/doc/process/weekly/week-4/members/zhoujingyou-weekly-summary-04.md b/doc/process/weekly/week-4/members/zhoujingyou-weekly-summary-04.md index cbbdd2c..93b585d 100644 --- a/doc/process/weekly/week-4/members/zhoujingyou-weekly-summary-04.md +++ b/doc/process/weekly/week-4/members/zhoujingyou-weekly-summary-04.md @@ -4,7 +4,7 @@ **姓  名:** 周竞由 **团队名称:** 软1-汪汪队 -**开始时间:** 2025-10-13 +**开始时间:** 2025-10-13 **结束时间:** 2025-10-19 ## 本周任务完成情况 From b9b34bea78e64501dac39bf3d833e1b035edfd5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E7=AB=9E=E7=94=B1?= <1193626695@qq.com> Date: Sun, 19 Oct 2025 19:03:11 +0800 Subject: [PATCH 10/12] =?UTF-8?q?=E5=91=A8=E7=AB=9E=E7=94=B1=E7=9A=84?= =?UTF-8?q?=E7=AC=AC=E5=9B=9B=E5=91=A8=E5=91=A8=E6=80=BB=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md b/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md index 65ae73c..5c5aa87 100644 --- a/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md +++ b/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md @@ -4,7 +4,7 @@ **姓  名:** 周竞由 **团队名称:** 软1-汪汪队 -**开始时间:** 2025-10-13 +**开始时间:** 2025-10-13 **结束时间:** 2025-10-19 ## 本周任务计划安排 From c60363da3ca99d317c4284b1dd34ce4db29cfa48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E7=AB=9E=E7=94=B1?= <1193626695@qq.com> Date: Sun, 19 Oct 2025 19:03:30 +0800 Subject: [PATCH 11/12] =?UTF-8?q?=E5=91=A8=E7=AB=9E=E7=94=B1=E7=9A=84?= =?UTF-8?q?=E7=AC=AC=E5=9B=9B=E5=91=A8=E5=91=A8=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md b/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md index 5c5aa87..809c7d5 100644 --- a/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md +++ b/doc/process/weekly/week-4/members/zhoujingyou-weekly-plan-4.md @@ -2,7 +2,7 @@ ## 姓名和起止时间 -**姓  名:** 周竞由 +**姓  名:** 周竞由 **团队名称:** 软1-汪汪队 **开始时间:** 2025-10-13 **结束时间:** 2025-10-19 From 1a08fb7e215009c335a6ca27747e924d3e215034 Mon Sep 17 00:00:00 2001 From: tianyuan <2861334240@qq.com> Date: Sun, 19 Oct 2025 19:52:07 +0800 Subject: [PATCH 12/12] =?UTF-8?q?=E5=B0=8F=E7=BB=84=E3=80=81=E6=9B=B9?= =?UTF-8?q?=E5=B3=BB=E8=8C=82=E7=AC=AC=E5=9B=9B=E5=91=A8=E6=80=BB=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weekly/week-4/group/weekly-summary-4.md | 33 +++++++++++++++++ .../week-4/members/caojunmao-weekly-plan-4.md | 2 +- .../members/caojunmao-weekly-summary-4.md | 37 +++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 doc/process/weekly/week-4/group/weekly-summary-4.md create mode 100644 doc/process/weekly/week-4/members/caojunmao-weekly-summary-4.md diff --git a/doc/process/weekly/week-4/group/weekly-summary-4.md b/doc/process/weekly/week-4/group/weekly-summary-4.md new file mode 100644 index 0000000..5655cb3 --- /dev/null +++ b/doc/process/weekly/week-4/group/weekly-summary-4.md @@ -0,0 +1,33 @@ +# 小组周总结-第4周 + +## 团队名称和起止时间 + +**团队名称:** 1班-汪汪队 +**开始时间:** 2023-10-13 +**结束时间:** 2023-10-19 + +## 本周任务完成情况 + +| 序号 | 总结内容 | 是否完成 | 情况说明 | +|------|----------|-----|----------| +| 1 | 确定分工 | 完成 | 2023-10-13 开会细分确定团队分工,统一开发工具 | +| 2 | 需求获取 | 完成 | 根据老师给出需求完成需求获取 | +| 3 | 学习 | 完成 | 根据分工学习MQTT或前端相关知识 | +| 4 | 实现基本的数据通信功能 | 基本完成 | 实现通过MQTT协议获取饮水机数据的基本功能 | +| 5 |尝试设计构建简易的ui草案| 进行中 |通过学习的前端知识尝试构建ui页面| + + +## 小结 + +1. **沟通协作:** 小组成员应积极主动沟通,遇到困难及时寻求帮助,也可以主动向指导老师及研究生学长寻求建议。 +2. **学习安排:** 小组成员仍处于软件开发专业知识的初步学习阶段,应合理安排自主学习时间,以便后续开发的顺利进行。 +3. **项目管理:** 项目进度管理杨安然同学及时推进项目流程,确保项目有条不紊。 + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. PM综合本小组成员工作情况提交小组周计划、周总结报告,按时上传至代码托管平台。 diff --git a/doc/process/weekly/week-4/members/caojunmao-weekly-plan-4.md b/doc/process/weekly/week-4/members/caojunmao-weekly-plan-4.md index 4e36cf8..90bc20c 100644 --- a/doc/process/weekly/week-4/members/caojunmao-weekly-plan-4.md +++ b/doc/process/weekly/week-4/members/caojunmao-weekly-plan-4.md @@ -4,7 +4,7 @@ **姓  名:** 曹峻茂 **团队名称:** 软1-汪汪队 -**开始时间:** 2023-10-013 +**开始时间:** 2023-10-13 **结束时间:** 2023-10-19 diff --git a/doc/process/weekly/week-4/members/caojunmao-weekly-summary-4.md b/doc/process/weekly/week-4/members/caojunmao-weekly-summary-4.md new file mode 100644 index 0000000..9b92585 --- /dev/null +++ b/doc/process/weekly/week-4/members/caojunmao-weekly-summary-4.md @@ -0,0 +1,37 @@ +# 个人周总结-第4周 + +## 姓名和起止时间 + +**姓  名:** 曹峻茂 +**团队名称:** 1班-汪汪队 +**开始时间:** 2023-10-13 +**结束时间:** 2023-10-19 + +## 本周任务完成情况 + +| 序号 | 总结内容 | 是否完成 | 情况说明 | +| ---- | ------------------------------------------------ |----|--------------------------------------------------------------| +| 3 | 学习 | 完成 | 学习MQTT协议知识 | +| 4 | 实现基本的数据通信功能 | 完成 | 实现通过MQTT协议获取饮水机数据的基本功能 | +| 4 | 召开例会,讨论原型的完成情况,并交换报告各自进度 | 完成 | 2023-10-19召开每周例会,并确定下周进度计划,需求 | + +## 对团队工作的建议 + +1. **互助学习:** 小组成员应该根据自身的技能长短开展互帮互助的活动,共同努力提高小组成员的专业水平; +2. **进度统一:** 团队成员尽量统一项目进度; + +## 小结 + +1. **原实现数据传输功能:** 完成了数据传输模块的基本实现; +2. **技能学习:** 小组成员各自开展自己所负责部分的个人技能的学习; +3. **项目管理:** PM及时推进项目进度,确保工作有条不紊; +4. **计划制定:** 根据本周任务完成情况与下一阶段文档提交要求,制定团队任务计划。 + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. 所有组员都需提交个人周计划、周总结文档,上传至代码托管平台; \ No newline at end of file