fix: relocate cwos-portal decompiled output to correct path; remove nested directory

Former-commit-id: dc30d42a8c55ed8b2382a41dc2434233fbed9930
This commit is contained in:
反编译工作区
2026-04-29 12:09:48 +08:00
parent ea8e492076
commit e8672a3c7b
1759 changed files with 547735 additions and 280 deletions
@@ -0,0 +1,25 @@
package cn.cloudwalk.elevator.mqtt.client;
import cn.cloudwalk.cloud.exception.ServiceException;
import cn.cloudwalk.cloud.result.CloudwalkResult;
import cn.cloudwalk.elevator.mqtt.fallback.MqttFeignClientFallback;
import cn.cloudwalk.elevator.mqtt.param.MqttSendMessageParam;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* 设备第三方 MQTT 发布入口:向指定 topic 推送 JSON 载荷(由 {@code /mqtt/publish} 落到底层 broker)。
*/
@FeignClient(name = "${feign.mqtt.name:cloudwalk-device-thirdparty}", path = "/mqtt",
fallback = MqttFeignClientFallback.class)
public interface MqttFeignClient {
/**
* 发布一条 MQTT 消息。
*
* @param paramMqttSendMessageParam topic 与 body(通常为业务侧 JSON 字符串)
* @return 是否投递成功,由下游服务定义成功语义
*/
@RequestMapping(value = {"/publish"}, method = {RequestMethod.POST})
CloudwalkResult<Boolean> publish(MqttSendMessageParam paramMqttSendMessageParam) throws ServiceException;
}
@@ -0,0 +1,22 @@
package cn.cloudwalk.elevator.mqtt.fallback;
import cn.cloudwalk.cloud.exception.ServiceException;
import cn.cloudwalk.cloud.result.CloudwalkResult;
import cn.cloudwalk.elevator.mqtt.client.MqttFeignClient;
import cn.cloudwalk.elevator.mqtt.param.MqttSendMessageParam;
import org.springframework.stereotype.Component;
/**
* {@link MqttFeignClient} 熔断/降级:调用失败时抛出运行时异常,促使上层按失败处理(不伪造成功投递)。
*/
@Component
public class MqttFeignClientFallback implements MqttFeignClient {
/**
* {@inheritDoc}
* @implSpec 不返回降级业务结果,直接抛错以暴露下游不可用
*/
@Override
public CloudwalkResult<Boolean> publish(MqttSendMessageParam param) throws ServiceException {
throw new RuntimeException("mqtt发送数据失败");
}
}
@@ -0,0 +1,87 @@
package cn.cloudwalk.elevator.mqtt.impl;
import cn.cloudwalk.cloud.exception.ServiceException;
import cn.cloudwalk.cloud.result.CloudwalkResult;
import cn.cloudwalk.cloud.utils.BeanCopyUtils;
import cn.cloudwalk.elevator.common.AbstractAcsDeviceService;
import cn.cloudwalk.elevator.mqtt.client.MqttFeignClient;
import cn.cloudwalk.elevator.mqtt.param.AcsElevatorRecordMqttParam;
import cn.cloudwalk.elevator.mqtt.param.MqttSendMessageParam;
import cn.cloudwalk.elevator.mqtt.service.MqttService;
import cn.cloudwalk.elevator.record.dao.AcsRecogRecordDao;
import cn.cloudwalk.elevator.record.dto.AcsElevatorRecordAddDTO;
import cn.cloudwalk.elevator.record.dto.AcsRecogRecordPageDTO;
import cn.cloudwalk.elevator.record.dto.AcsRecogRecordResultDTO;
import cn.cloudwalk.elevator.util.DateUtils;
import com.alibaba.fastjson.JSON;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* {@link MqttService} 实现:先短暂休眠以便识别明细入库,再按通行流水查人名、访客标签,向 {@code businessId + ELEVATOR_RECORD_SUFFIX} topic 推送 JSON。
*/
@Component
public class MqttServiceImpl extends AbstractAcsDeviceService implements MqttService {
/** 人员标签中表示「访客」的编码,与识别记录里 {@code personLabelIds} 包含关系判断一致。 */
private static final String VISITOR_LABEL_CODE = "1";
/** 与 {@link #VISITOR_LABEL_CODE} 对应的展示名,当前实现未参与逻辑,仅作文档对齐。 */
private static final String VISITOR_LABEL_NAME = "访客";
/** MQTT topic 后缀,与 {@code businessId} 拼接为完整 topic。 */
private static final String ELEVATOR_RECORD_SUFFIX = "_elevator_record";
@Qualifier("cn.cloudwalk.elevator.mqtt.client.MqttFeignClient")
@Resource
private MqttFeignClient mqttFeignClient;
@Resource
private AcsRecogRecordDao acsRecogRecordDao;
/**
* {@inheritDoc}
* <p>
* 异常在方法内记录日志后吞掉(除中断转 {@link ServiceException}),避免异步线程因下游偶发错误反复未捕获终止。
*/
@Override
@Async
public void sendInfoToOne(AcsElevatorRecordAddDTO addDTO) throws ServiceException {
this.logger.info("防止人员识别记录未入库即开始推送消息,休眠10秒");
try {
TimeUnit.SECONDS.sleep(10L);
} catch (InterruptedException e) {
this.logger.error("休眠失败,失败原因:{}", e.getMessage());
throw new ServiceException(e.getMessage());
}
try {
AcsRecogRecordPageDTO recordPageDTO = new AcsRecogRecordPageDTO();
recordPageDTO.setLogId(addDTO.getRecognitionFaceId());
recordPageDTO.setStartTime(DateUtils.todayStart());
recordPageDTO.setEndTime(DateUtils.todayEnd());
List<AcsRecogRecordResultDTO> recogRecordResultDTOS = this.acsRecogRecordDao.page(recordPageDTO);
if (!CollectionUtils.isEmpty(recogRecordResultDTOS)) {
AcsRecogRecordResultDTO acsRecogRecordResultDTO = recogRecordResultDTOS.get(0);
AcsElevatorRecordMqttParam acsElevatorRecordMqttParam =
(AcsElevatorRecordMqttParam)BeanCopyUtils.copyProperties(addDTO, AcsElevatorRecordMqttParam.class);
acsElevatorRecordMqttParam.setOpenDoorId(addDTO.getId());
acsElevatorRecordMqttParam.setPersonName(acsRecogRecordResultDTO.getPersonName());
if (StringUtils.isNotBlank(acsRecogRecordResultDTO.getPersonLabelIds())
&& acsRecogRecordResultDTO.getPersonLabelIds().contains(VISITOR_LABEL_CODE)) {
acsElevatorRecordMqttParam.setIsVisitor(Boolean.TRUE);
}
CloudwalkResult<Boolean> publish = this.mqttFeignClient
.publish(MqttSendMessageParam.builder().topic(addDTO.getBusinessId() + ELEVATOR_RECORD_SUFFIX)
.data(JSON.toJSONString(acsElevatorRecordMqttParam)).build());
if (publish.isSuccess()) {
this.logger.info("推送数据成功!!!,数据,{}", JSON.toJSONString(acsElevatorRecordMqttParam));
} else {
this.logger.debug("推送数据失败!!!");
}
}
} catch (Exception e) {
this.logger.error("发送消息失败 param:{} {}", addDTO, e.getMessage());
}
}
}
@@ -0,0 +1,6 @@
/**
* 电梯识别记录 MQTT 推送:经 {@code cloudwalk-device-thirdparty} 等下游将消息发布到业务 topic,供大屏/第三方订阅。
* <p>
* 与 {@code record} 域协作:在人员识别记录落库后异步组装载荷并调用发布接口。
*/
package cn.cloudwalk.elevator.mqtt;
@@ -0,0 +1,81 @@
package cn.cloudwalk.elevator.mqtt.param;
/**
* 推送到 MQTT 的电梯记录载荷:在 {@link cn.cloudwalk.elevator.record.dto.AcsElevatorRecordAddDTO} 基础上补全人名、开门流水 id、是否访客等,序列化为 {@code data} 字段内容。
*/
public class AcsElevatorRecordMqttParam {
private String openDoorId;
private String openDoorType;
private String srcFloor;
public void setOpenDoorId(String openDoorId) {
this.openDoorId = openDoorId;
}
private String destFloor;
private String dispatchElevatorNo;
private Long dispatchElevatorTime;
private String personName;
public void setOpenDoorType(String openDoorType) {
this.openDoorType = openDoorType;
}
public void setSrcFloor(String srcFloor) {
this.srcFloor = srcFloor;
}
public void setDestFloor(String destFloor) {
this.destFloor = destFloor;
}
public void setDispatchElevatorNo(String dispatchElevatorNo) {
this.dispatchElevatorNo = dispatchElevatorNo;
}
public void setDispatchElevatorTime(Long dispatchElevatorTime) {
this.dispatchElevatorTime = dispatchElevatorTime;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public void setIsVisitor(Boolean isVisitor) {
this.isVisitor = isVisitor;
}
public String getOpenDoorId() {
return this.openDoorId;
}
public String getOpenDoorType() {
return this.openDoorType;
}
public String getSrcFloor() {
return this.srcFloor;
}
public String getDestFloor() {
return this.destFloor;
}
public String getDispatchElevatorNo() {
return this.dispatchElevatorNo;
}
public Long getDispatchElevatorTime() {
return this.dispatchElevatorTime;
}
public String getPersonName() {
return this.personName;
}
private Boolean isVisitor = Boolean.valueOf(false);
public Boolean getIsVisitor() {
return this.isVisitor;
}
}
@@ -0,0 +1,61 @@
package cn.cloudwalk.elevator.mqtt.param;
import java.beans.ConstructorProperties;
/**
* Feign 发布请求体:MQTT topic 与一条 JSON 字符串形式的业务数据。
*/
public class MqttSendMessageParam {
private String topic;
private String data;
@ConstructorProperties({"topic", "data"})
MqttSendMessageParam(String topic, String data) {
this.topic = topic;
this.data = data;
}
public static MqttSendMessageParamBuilder builder() {
return new MqttSendMessageParamBuilder();
}
public static class MqttSendMessageParamBuilder {
private String topic;
public MqttSendMessageParamBuilder topic(String topic) {
this.topic = topic;
return this;
}
private String data;
public MqttSendMessageParamBuilder data(String data) {
this.data = data;
return this;
}
public MqttSendMessageParam build() {
return new MqttSendMessageParam(this.topic, this.data);
}
public String toString() {
return "MqttSendMessageParam.MqttSendMessageParamBuilder(topic=" + this.topic + ", data=" + this.data + ")";
}
}
public void setTopic(String topic) {
this.topic = topic;
}
public void setData(String data) {
this.data = data;
}
public String getTopic() {
return this.topic;
}
public String getData() {
return this.data;
}
}
@@ -0,0 +1,19 @@
package cn.cloudwalk.elevator.mqtt.service;
import cn.cloudwalk.cloud.exception.ServiceException;
import cn.cloudwalk.elevator.record.dto.AcsElevatorRecordAddDTO;
/**
* 将单条电梯通行/识别结果异步推送到 MQTT(供订阅方如大屏展示),与落库存在时序上的缓冲(实现内会短暂休眠后查库补全人名等)。
*/
public interface MqttService {
/**
* 按一条待写入或已关联的识别记录,组装业务 topic 与 JSON 后发起 {@link cn.cloudwalk.elevator.mqtt.client.MqttFeignClient#publish}。
* <p>
* 异步方法:调用方不应依赖其完成时刻做强一致逻辑。
*
* @param paramAcsElevatorRecordAddDTO 电梯识别记录主数据(需含 businessId、recognition 关联键等,供拼 topic 与反查人员)
* @throws ServiceException 睡眠被中断等不可恢复情况
*/
void sendInfoToOne(AcsElevatorRecordAddDTO paramAcsElevatorRecordAddDTO) throws ServiceException;
}