diff --git a/smart-switch-service/src/main/java/com/ruoyi/iot/receive/ReceiveController.java b/smart-switch-service/src/main/java/com/ruoyi/iot/receive/ReceiveController.java
index 30f5d97b..13f7059f 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/iot/receive/ReceiveController.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/iot/receive/ReceiveController.java
@@ -18,6 +18,8 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
/**
* 接收硬件参数
@@ -34,10 +36,10 @@ public class ReceiveController {
private String token;
@Autowired
- private IotService iotService;
+ private IotReceiveService iotReceiveService;
@Autowired
- private IotReceiveService iotReceiveService;
+ private ScheduledExecutorService scheduledExecutorService;
/**
* 功能描述:第三方平台数据接收。
@@ -52,11 +54,11 @@ public class ReceiveController {
@PostMapping(value = "/receive")
@Anonymous
public ResponseEntity receive(HttpServletRequest request){
- String body = HttpUtils.getBody(request);
- ObjBody obj = IotUtil.resolveBody(body, false);
- if (obj != null){
-// if (IotUtil.checkSignature(obj, token)){
-// log.info("receive成功参数:" + body);
+ // 异步处理,直接返回成功
+ scheduledExecutorService.schedule(() -> {
+ String body = HttpUtils.getBody(request);
+ ObjBody obj = IotUtil.resolveBody(body, false);
+ if (obj != null){
Object msg = obj.getMsg();
// 接收到msg
if (msg instanceof String) {
@@ -64,12 +66,10 @@ public class ReceiveController {
} else {
iotReceiveService.handleReceive(JSON.parseObject(JSON.toJSONString(msg), ReceiveMsg.class));
}
-// }else {
-// log.error("receive签名错误:" + body);
-// }
- }else {
- log.error("receive方法参数为空: body empty error");
- }
+ }else {
+ log.error("receive方法参数为空: body empty error");
+ }
+ }, 0, TimeUnit.SECONDS);
return new ResponseEntity<>(HttpStatus.OK);
}
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/Device.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/Device.java
index 8b540a51..eb8166f1 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/Device.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/Device.java
@@ -259,4 +259,17 @@ public class Device extends BaseEntity
@ApiModelProperty("电压系数")
private BigDecimal vxs;
+
+ @Excel(name = "用户手动操作类型", readConverterExp = "1=开启,2=关闭")
+ @ApiModelProperty("用户手动操作类型")
+ private String userOperaType;
+
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "用户手动操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty("用户手动操作时间")
+ private LocalDateTime userOperaTime;
+
+ @Excel(name = "用户手动操作时的总用电量")
+ @ApiModelProperty("用户手动操作时的总用电量")
+ private BigDecimal userOperaEle;
}
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/enums/DeviceUserOperaType.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/enums/DeviceUserOperaType.java
new file mode 100644
index 00000000..28af01b7
--- /dev/null
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/enums/DeviceUserOperaType.java
@@ -0,0 +1,21 @@
+package com.ruoyi.ss.device.domain.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+
+/**
+ * @author wjh
+ * 2024/12/26
+ */
+@Getter
+@AllArgsConstructor
+public enum DeviceUserOperaType {
+
+ OPEN("1", "开启"),
+ CLOSE("2", "关闭");
+
+ private final String type;
+ private final String msg;
+
+}
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/DeviceMapper.xml b/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/DeviceMapper.xml
index ab7c94e2..69e887f1 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/DeviceMapper.xml
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/DeviceMapper.xml
@@ -69,6 +69,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
sd.expire_ele,
sd.last_init_reading,
sd.vxs,
+ sd.user_opera_type,
+ sd.user_opera_time,
+ sd.user_opera_ele,
sm.model_name as model,
sm.picture as picture,
sm.tags as model_tags,
@@ -132,6 +135,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and sd.version like concat('%', #{query.version}, '%')
and find_in_set(#{query.modelTag}, sm.tags)
and sd.device_id != #{query.excludeDeviceId}
+ and user_opera_type = #{query.userOperaType}
and sd.store_id
not
@@ -396,6 +400,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
expire_ele,
last_init_reading,
vxs,
+ user_opera_type,
+ user_opera_time,
+ user_opera_ele,
#{storeId},
@@ -451,6 +458,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{expireEle},
#{lastInitReading},
#{vxs},
+ #{userOperaType},
+ #{userOperaTime},
+ #{userOperaEle},
@@ -537,6 +547,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
expire_ele = #{expireEle},
last_init_reading = #{lastInitReading},
vxs = #{vxs},
+ user_opera_type = #{userOperaType},
+ user_opera_time = #{userOperaTime},
+ user_opera_ele = #{userOperaEle},
where device_id = #{deviceId}
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/DeviceServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/DeviceServiceImpl.java
index 123b4b98..e3dd5288 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/DeviceServiceImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/DeviceServiceImpl.java
@@ -21,10 +21,7 @@ import com.ruoyi.ss.device.domain.DeviceQuery;
import com.ruoyi.ss.device.domain.dto.DeviceBatchUpdateModelDTO;
import com.ruoyi.ss.device.domain.dto.DeviceRegisterDTO;
import com.ruoyi.ss.device.domain.dto.DeviceWifiDTO;
-import com.ruoyi.ss.device.domain.enums.DeviceOnlineStatus;
-import com.ruoyi.ss.device.domain.enums.DevicePowerStatus;
-import com.ruoyi.ss.device.domain.enums.DeviceServiceMode;
-import com.ruoyi.ss.device.domain.enums.DeviceStatus;
+import com.ruoyi.ss.device.domain.enums.*;
import com.ruoyi.ss.device.domain.vo.DeviceMacSnVO;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.device.mapper.DeviceMapper;
@@ -369,6 +366,7 @@ public class DeviceServiceImpl implements DeviceService
@Override
public int switchDevice(Long deviceId, boolean open, String reason) {
DeviceVO device = selectById(deviceId);
+ this.pullDeviceInfo(device, IotConstants.ONLINE_TYPE_GET);
return this.switchDevice(device, open ? DevicePowerStatus.ON : DevicePowerStatus.OFF, reason);
}
@@ -813,10 +811,10 @@ public class DeviceServiceImpl implements DeviceService
// 校验
this.validatePreLogicDelete(deviceIds);
- // 拉取最新数据
- this.pullDeviceInfo(deviceIds, IotConstants.ONLINE_TYPE_GET);
// 查询设备列表
List deviceList = this.selectByIds(deviceIds);
+ // 拉取最新数据
+ this.pullDeviceInfoList(deviceList, IotConstants.ONLINE_TYPE_GET);
Integer result = transactionTemplate.execute(status -> {
// 关闭设备订单
@@ -867,7 +865,7 @@ public class DeviceServiceImpl implements DeviceService
/**
* 切换设备通电状态(通/断电)
*
- * @param device 设备id
+ * @param device 设备id
* @param powerStatus 通电状态
* @param reason
*/
@@ -876,18 +874,27 @@ public class DeviceServiceImpl implements DeviceService
ServiceUtil.assertion(device == null || device.getDeleted(), "设备不存在");
Integer result = transactionTemplate.execute(status -> {
- // 修改数据库通断电状态
- Device changePowerForm = new Device();
- changePowerForm.setDeviceId(device.getDeviceId());
- changePowerForm.setPowerStatus(powerStatus.getStatus());
- int update = deviceMapper.updateSmDevice(changePowerForm);
+ // 修改数据库
+ Device data = new Device();
+ data.setDeviceId(device.getDeviceId());
+ data.setPowerStatus(powerStatus.getStatus());
+ data.setUserOperaTime(LocalDateTime.now());
+ data.setUserOperaEle(device.getTotalElectriQuantity());
+ if (DevicePowerStatus.ON.equals(powerStatus)) {
+ data.setUserOperaType(DeviceUserOperaType.OPEN.getType());
+ } else {
+ data.setUserOperaType(DeviceUserOperaType.CLOSE.getType());
+ }
+ int update = deviceMapper.updateSmDevice(data);
// 操作设备
if (update == 1) {
if (DevicePowerStatus.ON.equals(powerStatus)) {
- iotService.open(device, reason);
+ boolean open = iotService.open(device, reason);
+ ServiceUtil.assertion(!open, "开启设备失败");
} else if (DevicePowerStatus.OFF.equals(powerStatus)) {
- iotService.close(device, reason);
+ boolean close = iotService.close(device, reason);
+ ServiceUtil.assertion(!close, "关闭设备失败");
} else {
throw new ServiceException("不支持的操作");
}
@@ -1308,7 +1315,9 @@ public class DeviceServiceImpl implements DeviceService
return iotService.setEle(device, device.getSurplusEleDb(), reason);
}
- // 监控设备信息,并对设备进行校准
+ /**
+ * 监控设备信息,并对设备进行校准
+ */
@Override
public void monitor(List deviceIds) {
DeviceQuery query = new DeviceQuery();
@@ -1321,23 +1330,30 @@ public class DeviceServiceImpl implements DeviceService
for (DeviceVO device : deviceList) {
try {
-
scheduledExecutorService.schedule(() -> {
// 若物联网设备的时长或者电量小于当前设备数据库的值,则执行一次同步(开启)
// 一般情况下,物联网设备的值会大于或等于当前数据库的值
long deviceSeconds = device.getRemainTime() == null ? 0 : device.getRemainTime().longValue();
if (device.getSurplusSecondsDb() > deviceSeconds) {
- this.syncTime(device.getDeviceId(), LocalDateTime.now(), "设备监控-同步时长");
+ this.syncTime(device.getDeviceId(), LocalDateTime.now(), "设备监控-同步ch时长");
}
if (device.getSurplusEleDb().compareTo(device.getSurplusEle()) > 0) {
this.syncEle(device.getDeviceId(), "设备监控-同步电量");
}
- // TODO 若当前设备数据库的时长或者电量<=0,且在这之后用户没有发open命令,则执行一次同步(关闭)
- if (device.getSurplusSecondsDb() <= 0) {
- // TODO
+
+ // 若当前设备数据库的时长或者电量<=0,且在这之后用户没有发open命令,则执行一次同步(关闭)
+ boolean hasOpen = DeviceUserOperaType.OPEN.getType().equals(device.getUserOperaType()); // 是否开启过
+ LocalDateTime lastOperaTime = device.getUserOperaTime(); // 上次开启的时间
+ BigDecimal lastOperaEle = device.getUserOperaEle(); // 上次开启的总用电量
+
+ boolean hasOpenAfterExpireTime = hasOpen && lastOperaTime != null && lastOperaTime.isAfter(device.getExpireTime()); // 是否在时间结束后开启
+ if (device.getSurplusSecondsDb() <= 0 && !hasOpenAfterExpireTime) {
+ this.switchDevice(device, DevicePowerStatus.OFF, "设备监控-发现异常未关闭设备");
}
- if (device.getSurplusEle().compareTo(device.getSurplusEleDb()) <= 0) {
- // TODO
+
+ boolean hasOpenAfterExpireEle = hasOpen && lastOperaEle != null && lastOperaEle.compareTo(device.getExpireEle()) > 0; // 是否在结束电量后开启
+ if (device.getSurplusEle().compareTo(device.getSurplusEleDb()) <= 0 && !hasOpenAfterExpireEle) {
+ this.switchDevice(device, DevicePowerStatus.OFF, "设备监控-发现异常未关闭设备");
}
},0, TimeUnit.SECONDS);
@@ -1345,9 +1361,6 @@ public class DeviceServiceImpl implements DeviceService
log.error("监控设备{}出错:{}", device.getDeviceNo(), e.getMessage());
}
}
-
-
-
}
/**
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/RechargeDepositAfterPay.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/RechargeDepositAfterPay.java
index 66f94b41..1130523e 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/RechargeDepositAfterPay.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/RechargeDepositAfterPay.java
@@ -4,6 +4,7 @@ import com.ruoyi.common.constant.IotConstants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.iot.service.IotService;
+import com.ruoyi.ss.device.domain.enums.DevicePowerStatus;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.device.service.DeviceService;
import com.ruoyi.ss.payBill.domain.PayBillVO;
@@ -47,10 +48,9 @@ public class RechargeDepositAfterPay implements AfterPay {
ServiceUtil.assertion(bill == null, "订单不存在");
ServiceUtil.assertion(!TransactionBillStatus.UNPAID_DEPOSIT.getStatus().equals(bill.getStatus()), "订单状态非待支付押金");
- deviceService.pullDeviceInfo(bill.getDeviceId(), IotConstants.ONLINE_TYPE_GET);
-
DeviceVO device = deviceService.selectById(bill.getDeviceId());
ServiceUtil.assertion(device == null, "设备不存在");
+ deviceService.pullDeviceInfo(device, IotConstants.ONLINE_TYPE_GET);
Integer result = transactionTemplate.execute(status -> {
// 修改订单信息
@@ -60,8 +60,6 @@ public class RechargeDepositAfterPay implements AfterPay {
data.setStatus(TransactionBillStatus.SUCCESS_DEPOSIT.getStatus());
data.setDepositPayId(payBill.getPayId());
data.setPayTime(DateUtils.toDate(payBill.getPayTime()));
- data.setDeviceRechargeStatus(TransactionBillDeviceRechargeStatus.SUCCESS.getStatus());
- data.setOpenMsg("成功");
TransactionBillQuery query = new TransactionBillQuery();
query.setBillId(bill.getBillId());
query.setStatus(TransactionBillStatus.UNPAID_DEPOSIT.getStatus());
@@ -72,28 +70,43 @@ public class RechargeDepositAfterPay implements AfterPay {
int received = transactionBillService.receiveMchShowMobileAmount(bill);
ServiceUtil.assertion(received != 1, "商户获取用户手机号扣款失败");
- // 开启设备
- this.openDevice(bill);
-
return update;
});
+ // 开启设备
+ this.openDevice(bill, device);
+
return result == null ? 0 : result;
}
/**
* 订单开启设备
*/
- private int openDevice(TransactionBillVO bill) {
+ private int openDevice(TransactionBillVO bill, DeviceVO device) {
try {
- iotService.open(bill, "分时段订单" + bill.getBillNo() + "开启");
- return 1;
+ Integer result = transactionTemplate.execute(status -> {
+ // 修改订单信息
+ TransactionBill data = new TransactionBill();
+ data.setBillId(bill.getBillId());
+ data.setDeviceRechargeStatus(TransactionBillDeviceRechargeStatus.SUCCESS.getStatus());
+ data.setOpenMsg("成功");
+ int update = transactionBillService.updateSmTransactionBill(data);
+ ServiceUtil.assertion(update != 1, "修改订单信息失败,状态已经发生改变:%s", bill.getBillNo());
+
+ // 操作设备
+ int switchDevice = deviceService.switchDevice(device, DevicePowerStatus.ON, "分时段订单" + bill.getBillNo() + "开启");
+ ServiceUtil.assertion(switchDevice != 1, "操作设备%s失败", device.getDeviceNo());
+
+ return update;
+ });
+
+ return result == null ? 0 : result;
} catch (Exception e) {
log.error(e.getMessage());
TransactionBill data = new TransactionBill();
+ data.setBillId(bill.getBillId());
data.setDeviceRechargeStatus(TransactionBillDeviceRechargeStatus.FAIL.getStatus());
data.setOpenMsg(e.getMessage());
- data.setBillId(bill.getBillId());
return transactionBillService.updateSmTransactionBill(data);
}
}
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java
index 51f67b58..9d125b58 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java
@@ -24,7 +24,7 @@ import com.ruoyi.ss.bonus.service.BonusService;
import com.ruoyi.ss.channelWithdraw.domain.ChannelWithdrawVO;
import com.ruoyi.ss.channelWithdraw.service.ChannelWithdrawService;
import com.ruoyi.dashboard.domain.vo.BillCountVo;
-import com.ruoyi.ss.device.domain.vo.DeviceIotResultVO;
+import com.ruoyi.ss.device.domain.enums.DevicePowerStatus;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.device.service.DeviceService;
import com.ruoyi.ss.payBill.domain.PayBillQuery;
@@ -1049,7 +1049,8 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
} else if(SuitFeeType.TIMING_TIME.getType().equals(order.getSuitFeeType())){
deviceService.resetTime(device, false, reason);
}
- iotService.close(device, reason);
+ int switchDevice = deviceService.switchDevice(device, DevicePowerStatus.OFF, reason);
+ ServiceUtil.assertion(switchDevice != 1, "操作设备失败");
}
return update;
@@ -1919,28 +1920,23 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
DeviceVO device = deviceService.selectById(bill.getDeviceId());
ServiceUtil.assertion(device == null, "设备不存在");
- ServiceUtil.assertion(StringUtils.isBlank(device.getMac()), "设备MAC为空,请联系管理员处理");
+ ServiceUtil.assertion(StringUtils.isAllBlank(device.getMac(), device.getMac2()), "设备MAC为空,请联系管理员处理");
+ deviceService.pullDeviceInfo(device, IotConstants.ONLINE_TYPE_GET);
+ // 开启
if (open) {
+ // 分时段订单,直接open
if (SuitFeeType.timingList().contains(bill.getSuitFeeType())) {
- return iotService.open(device, "订单" + bill.getBillNo() + "临时开启") ? 1 : 0;
- } else {
- // 计算设备剩余时长
- LocalDateTime expireTime = device.getExpireTime();
- if (expireTime == null) {
- return 0;
- }
- Duration between = Duration.between(LocalDateTime.now(), expireTime);
- if (between.getSeconds() > 0) {
- CommandResponse res = iotService.setTime(device, between.getSeconds(), "订单" + bill.getBillNo() + "临时开启");
- return res.isSuccess() ? 1 : 0;
- }
+ return deviceService.switchDevice(device, DevicePowerStatus.ON, "分时段订单" + bill.getBillNo() + "临时开启");
+ }
+ // 其余订单,同步时长
+ else {
+ CommandResponse res = deviceService.syncTime(device.getDeviceId(), LocalDateTime.now(), "时长订单" + bill.getBillNo() + "临时开启");
+ return res != null && res.isSuccess() ? 1 : 0;
}
} else {
- return iotService.close(device, "订单" + bill.getBillNo() + "临时关闭") ? 1 : 0;
+ return deviceService.switchDevice(device, DevicePowerStatus.OFF, "订单" + bill.getBillNo() + "临时关闭");
}
-
- return 0;
}
@Override
diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppDeviceController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppDeviceController.java
index d7b3554c..705d49fb 100644
--- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppDeviceController.java
+++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppDeviceController.java
@@ -20,7 +20,6 @@ import com.ruoyi.ss.device.domain.DeviceQuery;
import com.ruoyi.ss.device.domain.dto.DeviceRegisterDTO;
import com.ruoyi.ss.device.domain.dto.DeviceWifiDTO;
import com.ruoyi.ss.device.domain.enums.DevicePowerStatus;
-import com.ruoyi.ss.device.domain.vo.DeviceIotResultVO;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.device.service.DeviceAssembler;
import com.ruoyi.ss.device.service.DeviceConverter;
@@ -130,15 +129,19 @@ public class AppDeviceController extends BaseController {
@ApiOperation("设备通断电")
@PutMapping("/{deviceId}/changePower")
public AjaxResult close(@PathVariable @ApiParam("设备id") Long deviceId, String status) {
+ DeviceVO device = smDeviceService.selectById(deviceId);
+ ServiceUtil.assertion(device == null, "设备不存在");
+
// 判断是否有权限更改
if (!deviceValidator.canOpera(deviceId, getUserId()) ) {
return error("您无权操作此设备");
}
- DeviceVO device = smDeviceService.selectById(deviceId);
- ServiceUtil.assertion(device == null, "设备不存在");
deviceAssembler.assembleAllowSwitch(device, getUserId());
ServiceUtil.assertion(!device.getAllowSwitch(), "您无权操作此设备");
+ // 获取最新数据
+ smDeviceService.pullDeviceInfo(device, IotConstants.ONLINE_TYPE_GET);
+
DevicePowerStatus powerStatus = DevicePowerStatus.parse(status);
return toAjax(smDeviceService.switchDevice(device, powerStatus, "商户开关设备"));
}