This commit is contained in:
磷叶 2024-12-01 15:32:12 +08:00
parent b2c23342d8
commit 391695de15
15 changed files with 215 additions and 139 deletions

View File

@ -247,4 +247,8 @@ public class Device extends BaseEntity
@ApiModelProperty("设备版本号")
@JsonView(JsonViewProfile.App.class)
private String version;
@Excel(name = "结束使用的电量")
@ApiModelProperty("结束使用的电量")
private BigDecimal expireEle;
}

View File

@ -210,4 +210,11 @@ public interface DeviceMapper
*/
int bindAgent(@Param("deviceId") Long deviceId,@Param("agentId") Long agentId, @Param("agentServiceRate") BigDecimal agentServiceRate);
/**
* 增加电量
* @param deviceId
* @param amount 电量
* @return
*/
int addEle(@Param("deviceId") Long deviceId, @Param("amount") BigDecimal amount);
}

View File

@ -6,6 +6,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="DeviceVO" id="SmDeviceResult" autoMapping="true">
<result property="totalElectriQuantity" column="total_electri_quantity" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="expireEle" column="expire_ele" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="surplusEle" column="surplus_ele" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="initReading" column="init_reading" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="modelTags" column="model_tags" typeHandler="com.ruoyi.system.mapper.typehandler.StringSplitListTypeHandler" />
</resultMap>
@ -64,6 +66,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
sd.month_fee,
sd.last_recover_time,
sd.version,
sd.expire_ele,
sm.model_name as model,
sm.picture as picture,
sm.tags as model_tags,
@ -388,6 +391,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="onlineStatus1 != null">online_status1,</if>
<if test="onlineStatus2 != null">online_status2,</if>
<if test="version != null">version,</if>
<if test="expireEle != null">expire_ele,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="storeId != null">#{storeId},</if>
@ -440,9 +444,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="onlineStatus1 != null">#{onlineStatus1},</if>
<if test="onlineStatus2 != null">#{onlineStatus2},</if>
<if test="version != null">#{version},</if>
<if test="expireEle != null">#{expireEle},</if>
</trim>
</insert>
<update id="addEle">
update sm_device
set expire_ele = IF(
(expire_ele is null) or (total_electri_quantity > expire_time),
total_electri_quantity + #{amount},
expire_ele + #{amount}
)
where device_id = #{deviceId} and deleted = false
</update>
<update id="addTime">
update sm_device
set expire_time = IF (
@ -513,6 +528,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="onlineStatus1 != null">online_status1 = #{onlineStatus1},</if>
<if test="onlineStatus2 != null">online_status2 = #{onlineStatus2},</if>
<if test="version != null">version = #{version},</if>
<if test="expireEle != null">expire_ele = #{expireEle},</if>
</trim>
where device_id = #{deviceId}
</update>

View File

@ -82,8 +82,11 @@ public interface DeviceService
* @param deviceId 设备id
* @param seconds 时长
* @param withIot 是否充值物联网设备
* @param reason
*/
boolean addTime(Long deviceId, long seconds, boolean withIot);
boolean addTime(Long deviceId, long seconds, boolean withIot, String reason);
boolean addTime(DeviceVO device, long seconds, boolean withIot, String reason);
/**
* 逻辑删除
@ -231,8 +234,6 @@ public interface DeviceService
*/
void deviceHeartBeat();
boolean addTimeByUser(Long deviceId, long seconds, boolean withIot, String reason);
/**
* 设备录入
*/
@ -317,13 +318,15 @@ public interface DeviceService
/**
* 电量归零并关闭订单
*/
int resetEleWithBill(Long deviceId, boolean requiredIot);
int resetEleWithBill(Long deviceId, boolean requiredIot, BigDecimal totalEle);
/**
* 添加电量
*/
boolean addEle(Long deviceId, BigDecimal amount, boolean withIot, String reason);
boolean addEle(DeviceVO device, BigDecimal amount, boolean withIot, String reason);
int updateLastRecoverTime(Long deviceId, Long lastRecoverTime);
/**
@ -384,4 +387,11 @@ public interface DeviceService
* 查询员工设备列表
*/
List<DeviceVO> selectStaffDeviceList(DeviceQuery query);
/**
* 尝试关闭该设备未结束的所有订单
* @param device 设备
* @param totalEle 总用电量
*/
int closeNotFinishedBill(DeviceVO device, BigDecimal totalEle);
}

View File

@ -1,7 +1,6 @@
package com.ruoyi.ss.device.service.impl;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.core.redis.enums.RedisLockKey;
import com.ruoyi.common.enums.LoginType;
@ -328,23 +327,6 @@ public class DeviceServiceImpl implements DeviceService
return deviceMapper.selectSmDeviceList(dto);
}
@Override
public boolean addTimeByUser(Long deviceId, long seconds, boolean withIot, String reason) {
boolean addTime = this.addTime(deviceId, seconds, withIot);
if (addTime) {
// 记录下操作日志
LoginUser loginUser = SecurityUtils.getLoginUser();
scheduledExecutorService.schedule(() -> {
DeviceVO device = deviceMapper.selectSmDeviceByDeviceId(deviceId);
recordTimeService.insertRecordTime(recordTimeConverter.toRecordTime(device, seconds, reason, loginUser, RecordTimeType.TIME.getType()));
}, 0, TimeUnit.SECONDS);
}
return addTime;
}
@Override
public int register(DeviceRegisterDTO dto) {
if (dto == null) {
@ -517,37 +499,23 @@ public class DeviceServiceImpl implements DeviceService
}
private void resetRecord(DeviceVO device, RecordTimeType type, String reason) {
LoginUser loginUser;
try {
loginUser = SecurityUtils.getLoginUser();
} catch (Exception e) {
loginUser = null;
}
LoginUser finalLoginUser = loginUser;
scheduledExecutorService.schedule(() -> {
RecordTime record = null;
// 电量
if (RecordTimeType.ELE.equals(type)) {
int amount = device.getSurplusEle().negate().intValue();
record = recordTimeConverter.toRecordTime(
device,
amount,
reason,
finalLoginUser,
RecordTimeType.ELE.getType()
);
}
// 时长
else if (RecordTimeType.TIME.equals(type)) {
Duration duration = Duration.between(LocalDateTime.now(), device.getExpireTime());
long seconds = duration.getSeconds() > 0 ? duration.getSeconds() : 0;
record = recordTimeConverter.toRecordTime(device, -seconds, "设备归零", finalLoginUser, RecordTimeType.TIME.getType());
}
if (record != null) {
// 电量
if (RecordTimeType.ELE.equals(type)) {
int amount = device.getSurplusEle().negate().intValue();
RecordTime record = recordTimeConverter.toRecordTime(device.getDeviceId(), amount, reason, RecordTimeType.ELE.getType());
scheduledExecutorService.schedule(() -> {
recordTimeService.insertRecordTime(record);
}
}, 0, TimeUnit.SECONDS);
}, 0, TimeUnit.SECONDS);
}
// 时长
else if (RecordTimeType.TIME.equals(type)) {
Duration duration = Duration.between(LocalDateTime.now(), device.getExpireTime());
long seconds = duration.getSeconds() > 0 ? duration.getSeconds() : 0;
RecordTime record = recordTimeConverter.toRecordTime(device.getDeviceId(), -seconds, reason, RecordTimeType.TIME.getType());
scheduledExecutorService.schedule(() -> {
recordTimeService.insertRecordTime(record);
}, 0, TimeUnit.SECONDS);
}
}
private int resetUpdateDbEle(Long deviceId) {
@ -583,7 +551,7 @@ public class DeviceServiceImpl implements DeviceService
query.setSuitFeeTypes(SuitFeeType.rechargeTimeList());
List<TransactionBillVO> billList = transactionBillService.selectSmTransactionBillList(query);
try {
int closeCount = transactionBillService.batchCloseBillByDevice(billList, false, device);
int closeCount = transactionBillService.batchCloseBillByDevice(billList, false, device, null);
ServiceUtil.assertion(closeCount != billList.size(), "关闭订单失败:closeCount =" + closeCount);
} catch (Exception e) {
log.error("关闭订单失败:{}" , e.getMessage());
@ -597,7 +565,7 @@ public class DeviceServiceImpl implements DeviceService
}
@Override
public int resetEleWithBill(Long deviceId, boolean requiredIot) {
public int resetEleWithBill(Long deviceId, boolean requiredIot, BigDecimal totalEle) {
if (deviceId == null) {
return 0;
}
@ -615,7 +583,7 @@ public class DeviceServiceImpl implements DeviceService
query.setSuitFeeTypes(SuitFeeType.rechargeCountList());
List<TransactionBillVO> billList = transactionBillService.selectSmTransactionBillList(query);
try {
int closeCount = transactionBillService.batchCloseBillByDevice(billList, false, device);
int closeCount = transactionBillService.batchCloseBillByDevice(billList, false, device, totalEle);
ServiceUtil.assertion(closeCount != billList.size(), "关闭订单失败:closeCount =" + closeCount);
} catch (Exception e) {
log.error("关闭订单失败:{}" , e.getMessage());
@ -631,25 +599,41 @@ public class DeviceServiceImpl implements DeviceService
@Override
public boolean addEle(Long deviceId, BigDecimal ele, boolean withIot, String reason) {
DeviceVO device = selectById(deviceId);
return this.addEle(device, ele, withIot, reason);
}
@Override
public boolean addEle(DeviceVO device, BigDecimal amount, boolean withIot, String reason) {
if (device == null) {
return false;
}
boolean result = false;
if (withIot) {
CommandResponse res = iotService.addEle(device, ele);
result = res.isSuccess();
}
Integer result = transactionTemplate.execute(status -> {
// 更新设备电量
int update = deviceMapper.addEle(device.getDeviceId(), amount);
ServiceUtil.assertion(update != 1, "更新电量失败");
// 记录下操作日志
if (result) {
LoginUser loginUser = SecurityUtils.getLoginUser();
scheduledExecutorService.schedule(() -> {
recordTimeService.insertRecordTime(recordTimeConverter.toRecordTime(device, ele.longValue(), reason, loginUser, RecordTimeType.ELE.getType()));
}, 0, TimeUnit.SECONDS);
}
// 记录日志
RecordTime record = recordTimeConverter.toRecordTime(device.getDeviceId(), amount.longValue(), reason, RecordTimeType.ELE.getType());
int insertRecord = recordTimeService.insertRecordTime(record);
ServiceUtil.assertion(insertRecord != 1, "记录电量变化失败");
return true;
if (withIot) {
// 若设备剩余电量小于0则补偿电量充值
CommandResponse res;
if (device.getSurplusEle().compareTo(BigDecimal.ZERO) < 0) {
res = iotService.addEle(device, amount.subtract(device.getSurplusEle()));
} else {
res = iotService.addEle(device, amount);
}
boolean iot = res.isSuccess();
ServiceUtil.assertion(!iot, "为设备充值电量失败");
}
return update;
});
return result != null && result == 1;
}
@Override
@ -824,21 +808,29 @@ public class DeviceServiceImpl implements DeviceService
@Override
public boolean addTime(Long deviceId, long seconds, boolean withIot) {
ServiceUtil.assertion( seconds < 0, "增加的时长不允许小于0");
public boolean addTime(Long deviceId, long seconds, boolean withIot, String reason) {
DeviceVO device = deviceMapper.selectSmDeviceByDeviceId(deviceId);
ServiceUtil.assertion(device == null, "设备不存在");
return addTime(device, seconds, withIot, reason);
}
@Override
public boolean addTime(DeviceVO device, long seconds, boolean withIot, String reason) {
ServiceUtil.assertion( seconds < 0, "增加的时长不允许小于0");
ServiceUtil.assertion(device == null || device.getDeviceId() == null, "设备不存在");
ServiceUtil.assertion(!StringUtils.hasText(device.getMac()), "设备MAC号为空");
ServiceUtil.assertion(DeviceStatus.FIXING.getStatus().equals(device.getStatus()), "设备正在维修中,无法使用");
Long deviceId = device.getDeviceId();
Boolean result = transactionTemplate.execute(status -> {
// 更新数据库时长
int updateCount = deviceMapper.addTime(deviceId, seconds);
ServiceUtil.assertion(updateCount != 1, "增加时长失败,请刷新后重试");
// 修改状态为使用中
changeStatus(deviceId, DeviceStatus.USING);
// 记录下操作日志
RecordTime record = recordTimeConverter.toRecordTime(deviceId, seconds, reason, RecordTimeType.TIME.getType());
int insertRecord = recordTimeService.insertRecordTime(record);
ServiceUtil.assertion(insertRecord != 1, "记录时长变化日志失败");
// 物联网设备增加时长
if (withIot) {
@ -857,11 +849,6 @@ public class DeviceServiceImpl implements DeviceService
if (success) {
// 拉取设备信息
this.pullDeviceInfoAsync(Collections.singletonList(deviceId), 3, TimeUnit.SECONDS);
// 时长结束后修改设备状态
// scheduledExecutorService.schedule(()-> {
// freshStatus(deviceId);
// }, seconds, TimeUnit.SECONDS);
}
return success;
@ -965,7 +952,7 @@ public class DeviceServiceImpl implements DeviceService
query.setDeviceId(deviceId);
query.setIsFinished(false);
List<TransactionBillVO> billList = transactionBillService.selectSmTransactionBillList(query);
int closeCount = transactionBillService.batchCloseBillByDevice(billList, false, device);
int closeCount = transactionBillService.batchCloseBillByDevice(billList, false, device, null);
ServiceUtil.assertion(closeCount != billList.size(), "关闭订单失败:closeCount =" + closeCount);
}
@ -1266,18 +1253,8 @@ public class DeviceServiceImpl implements DeviceService
ServiceUtil.assertion(device == null || device.getDeleted(), "设备不存在");
Integer result = transactionTemplate.execute(status -> {
// 尝试关闭该设备未结束的所有订单
TransactionBillQuery query = new TransactionBillQuery();
query.setStatusList(TransactionBillStatus.canClose());
query.setDeviceId(device.getDeviceId());
query.setIsFinished(false); // 未结束的订单都会被关闭
List<TransactionBillVO> billList = transactionBillService.selectSmTransactionBillList(query);
try {
int closeCount = transactionBillService.batchCloseBillByDevice(billList, false, device);
ServiceUtil.assertion(closeCount != billList.size(), "关闭订单失败:closeCount =" + closeCount);
} catch (Exception e) {
log.error("关闭订单失败: {}", e.getMessage());
}
// 关闭未完成订单
this.closeNotFinishedBill(device, null);
// 修改设备信息
int timeUpdate = this.resetUpdateDbTime(deviceId);
@ -1310,6 +1287,33 @@ public class DeviceServiceImpl implements DeviceService
return result == null ? 0 : result;
}
/**
* 尝试关闭该设备未结束的所有订单
* @param device 设备
* @param totalEle 总用电量
*/
@Override
public int closeNotFinishedBill(DeviceVO device, BigDecimal totalEle) {
if (device == null || device.getDeviceId() == null) {
return 0;
}
TransactionBillQuery query = new TransactionBillQuery();
query.setStatusList(TransactionBillStatus.canClose());
query.setDeviceId(device.getDeviceId());
query.setIsFinished(false); // 未结束的订单都会被关闭
List<TransactionBillVO> billList = transactionBillService.selectSmTransactionBillList(query);
int closeCount = 0;
try {
closeCount = transactionBillService.batchCloseBillByDevice(billList, false, device, totalEle);
ServiceUtil.assertion(closeCount != billList.size(), "关闭订单失败:closeCount =" + closeCount);
} catch (Exception e) {
log.error("关闭订单失败: {}", e.getMessage());
}
return closeCount;
}
/**
* 设备是否已经被绑定
*

View File

@ -1,7 +1,5 @@
package com.ruoyi.ss.record.time.service;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.ss.device.domain.Device;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.record.time.domain.RecordTime;
import com.ruoyi.ss.user.domain.SmUserVO;
@ -12,7 +10,7 @@ import com.ruoyi.ss.user.domain.SmUserVO;
*/
public interface RecordTimeConverter {
RecordTime toRecordTime(Device device, long amount, String reason, LoginUser loginUser, String type);
RecordTime toRecordTime(Long deviceId, long amount, String reason, String type);
RecordTime toRecordTime(DeviceVO device, long secondSuitTime, String reason, SmUserVO user, String type);
}

View File

@ -2,12 +2,13 @@ package com.ruoyi.ss.record.time.service.impl;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.LoginType;
import com.ruoyi.ss.device.domain.Device;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.record.time.domain.RecordTime;
import com.ruoyi.ss.record.time.domain.enums.OperatorType;
import com.ruoyi.ss.record.time.service.RecordTimeConverter;
import com.ruoyi.ss.user.domain.SmUserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
@ -17,19 +18,27 @@ import java.time.LocalDateTime;
* 2024/6/6
*/
@Service
@Slf4j
public class RecordTimeConverterImpl implements RecordTimeConverter {
@Override
public RecordTime toRecordTime(Device device, long amount, String reason, LoginUser loginUser, String type) {
public RecordTime toRecordTime(Long deviceId, long amount, String reason, String type) {
RecordTime record = new RecordTime();
record.setDeviceId(device == null ? null : device.getDeviceId());
record.setDeviceId(deviceId);
record.setAmount(amount);
record.setReason(reason);
record.setType(type);
if (loginUser != null) {
record.setOperatorId(loginUser.getUserId());
record.setOperatorName(loginUser.getUsername());
record.setOperatorType(toOperatorType(loginUser.getLoginType()));
try {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) {
record.setOperatorId(loginUser.getUserId());
record.setOperatorName(loginUser.getUsername());
record.setOperatorType(toOperatorType(loginUser.getLoginType()));
}
} catch (Exception e) {
log.warn(e.getMessage());
}
record.setOperatorTime(LocalDateTime.now());
return record;

View File

@ -148,9 +148,8 @@ public interface TransactionBillService
* 手动设备充值
*
* @param billId
* @param tryCount
*/
boolean rechargeDevice(Long billId, int tryCount);
boolean rechargeDevice(Long billId);
/**
* 查询设备充值失败列表
@ -236,7 +235,7 @@ public interface TransactionBillService
/**
* 根据设备ID批量结束订单
*/
int batchCloseBillByDevice(List<TransactionBillVO> billList, boolean withDevice, DeviceVO device);
int batchCloseBillByDevice(List<TransactionBillVO> billList, boolean withDevice, DeviceVO device, BigDecimal totalEle);
/**
* 获取用户提现手续费信息

View File

@ -15,13 +15,11 @@ import com.ruoyi.ss.suit.domain.enums.SuitFeeType;
import com.ruoyi.ss.transactionBill.domain.TransactionBill;
import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery;
import com.ruoyi.ss.transactionBill.domain.bo.PaySuccessBO;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillDeviceRechargeStatus;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillType;
import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO;
import com.ruoyi.ss.transactionBill.service.TransactionAssembler;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import com.ruoyi.ss.user.service.ISmUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
@ -124,8 +122,8 @@ public class RechargePayHandler implements AfterPay, AfterRefund {
// 操作成功
if (result != null && result == 1) {
// 充值设备尝试2次
transactionBillService.rechargeDevice(bill.getBillId(), 2);
// 充值设备
transactionBillService.rechargeDevice(bill.getBillId());
// 5秒后设备设置语音播报
scheduledExecutorService.schedule(() -> {

View File

@ -892,11 +892,11 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
/**
* 订单设备充值
*
* @param billId 订单ID
* @param tryCount 尝试次数
*/
@Override
public boolean rechargeDevice(Long billId, int tryCount) {
public boolean rechargeDevice(Long billId) {
ServiceUtil.assertion(billId == null, "参数错误,billId不允许为空");
// ServiceUtil.assertion(!redisLock.lock(RedisLockKey.RECHARGE_DEVICE, billId), "当前设备充值请求过于频繁,请等待");
try {
@ -935,13 +935,13 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
if (SuitFeeType.TIME.getType().equals(bill.getSuitFeeType())) {
// 设备设置时长
long seconds = transactionBillConverter.toRechargeSeconds(bill);
int setTime = deviceService.setTime(device, seconds, tryCount);
ServiceUtil.assertion(setTime != 1, "设备时长充值失败");
boolean addTime = deviceService.addTime(device, seconds, true, "充值订单:" + bill.getBillNo());
ServiceUtil.assertion(!addTime, "设备时长充值失败");
} else if (SuitFeeType.COUNT.getType().equals(bill.getSuitFeeType())) {
// 设备设置电量
BigDecimal ele = transactionBillConverter.toRechargeEle(bill);
int setEle = deviceService.setEle(device, ele, tryCount);
ServiceUtil.assertion(setEle != 1, "设备时长充值失败");
boolean addEle = deviceService.addEle(device, ele, true, "充值订单:" + bill.getBillNo());
ServiceUtil.assertion(!addEle, "设备时长充值失败");
} else {
throw new ServiceException("不支持的套餐类型");
}
@ -984,12 +984,15 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
return 0;
}
LocalDateTime startTime = LocalDateTime.now();
LocalDateTime now = LocalDateTime.now();
LocalDateTime startTime = device.getExpireTime() == null || now.isAfter(device.getExpireTime()) ? now : device.getExpireTime();
BigDecimal startEle = device.getExpireEle() == null || device.getExpireEle().compareTo(device.getTotalElectriQuantity()) < 0 ?
device.getTotalElectriQuantity() : device.getExpireEle();
TransactionBill data = new TransactionBill();
data.setBillId(bill.getBillId());
data.setSuitStartTime(startTime);
data.setSuitStartEle(device.getTotalElectriQuantity());
data.setSuitStartEle(startEle);
// 充值时长
if (SuitFeeType.TIME.getType().equals(bill.getSuitFeeType())) {
@ -1000,7 +1003,8 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
}
// 充值电量
else if (SuitFeeType.COUNT.getType().equals(bill.getSuitFeeType())) {
data.setSuitEndEle(device.getTotalElectriQuantity().add(transactionBillConverter.toRechargeEle(bill)));
BigDecimal endEle = startEle.add(transactionBillConverter.toRechargeEle(bill));
data.setSuitEndEle(endEle);
}
return transactionBillMapper.updateSmTransactionBill(data);
}
@ -1061,7 +1065,7 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
return;
}
try {
boolean result = rechargeDevice(billId, 1);
boolean result = rechargeDevice(billId);
ServiceUtil.assertion(!result, String.format("尝试充值设备失败:billId=%s:剩余次数:%s,", billId, tryCount - 1));
} catch (Exception e) {
this.tryRechargeDevice(billId, tryCount - 1);
@ -1709,7 +1713,7 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
ServiceUtil.assertion(updateInfo != 1, "更新套餐使用信息失败");
// 修改剩余时间
boolean addTime = deviceService.addTime(bill.getDeviceId(), transactionBillConverter.toRechargeSeconds(bill), false);
boolean addTime = deviceService.addTime(bill.getDeviceId(), transactionBillConverter.toRechargeSeconds(bill), false, "蓝牙充值订单:" + bill.getBillNo());
ServiceUtil.assertion(!addTime, "修改剩余时间失败");
return result;
@ -1925,12 +1929,13 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
}
@Override
public int batchCloseBillByDevice(List<TransactionBillVO> billList, boolean withDevice, DeviceVO device) {
public int batchCloseBillByDevice(List<TransactionBillVO> billList, boolean withDevice, DeviceVO device, BigDecimal totalEle) {
if (CollectionUtils.isEmptyElement(billList)) {
return 0;
}
EndUseBO bo = new EndUseBO();
bo.setDevice(device);
bo.setTotalEle(totalEle);
if (CollectionUtils.isNotEmptyElement(billList)) {
Integer result = transactionTemplate.execute(status -> {

View File

@ -77,6 +77,7 @@ public class TransactionBillValidatorImpl extends BaseValidator implements Trans
}
RechargeDTO dto = bo.getParams();
SuitVO suit = bo.getSuit();
// 门店
StoreVo store = bo.getStore();
@ -118,7 +119,18 @@ public class TransactionBillValidatorImpl extends BaseValidator implements Trans
query.setDeviceId(device.getDeviceId());
List<TransactionBillVO> usingBill = transactionBillService.selectUsingBill(query);
if (CollectionUtils.isNotEmptyElement(usingBill)) {
return error("该设备有正在使用中的订单,暂时无法下单");
// 仅允许正在使用中的用户继续下单
List<Long> allowUserIds = usingBill.stream().map(TransactionBillVO::getUserId).collect(Collectors.toList());
ServiceUtil.assertion(!allowUserIds.contains(user.getUserId()), "该设备有正在使用中的订单,暂时无法下单");
// 不允许续分时段订单
TransactionBillVO timingBill = usingBill.stream()
.filter(bill -> SuitFeeType.timingList().contains(bill.getSuitFeeType()))
.findFirst().orElse(null);
ServiceUtil.assertion(timingBill != null, "当前设备存在正在使用中的分时段订单,无法下单");
// 仅允许续时长单
ServiceUtil.assertion(!Objects.equals(suit.getFeeType(), SuitFeeType.TIME.getType()), "当前存在正在使用中的订单,仅允许续时长订单");
}
// 商户检查
@ -132,7 +144,6 @@ public class TransactionBillValidatorImpl extends BaseValidator implements Trans
}
// 套餐检查
SuitVO suit = bo.getSuit();
if (suit == null) {
return error("当前设备套餐不存在");
}

View File

@ -207,7 +207,7 @@ public class AppDeviceController extends BaseController {
return error("非法的时长单位");
}
long seconds = amount.multiply(new BigDecimal(unit.getConversion())).longValue();
return toAjax(smDeviceService.addTimeByUser(deviceId, seconds, withIot, "商户手动充值"));
return toAjax(smDeviceService.addTime(deviceId, seconds, withIot, "商户手动充值"));
}
}

View File

@ -13,7 +13,9 @@ import com.ruoyi.common.enums.OperatorType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.dashboard.domain.vo.BillCountVo;
import com.ruoyi.ss.device.service.DeviceService;
import com.ruoyi.ss.device.service.DeviceValidator;
import com.ruoyi.ss.suit.domain.enums.SuitFeeType;
import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery;
import com.ruoyi.ss.transactionBill.domain.bo.EndUseBO;
import com.ruoyi.ss.transactionBill.domain.dto.*;
@ -71,6 +73,9 @@ public class AppTransactionBillController extends BaseController
@Autowired
private ISmUserService userService;
@Autowired
private DeviceService deviceService;
/**
* 查询充值记录列表
*/
@ -304,18 +309,27 @@ public class AppTransactionBillController extends BaseController
if (!transactionBillValidator.isUser(bo.getOrder(), getUserId()) && !transactionBillValidator.isMch(bo.getOrder(), getUserId())) {
return error("您不是该订单的用户或商户,无法结束订单");
}
return success(transactionBillService.endUse(bo, true ));
TransactionBillVO order = bo.getOrder();
if (SuitFeeType.rechargeTimeList().contains(order.getSuitFeeType())) {
return toAjax(deviceService.resetTimeWithBill(order.getDeviceId(), false));
} else if (SuitFeeType.rechargeCountList().contains(order.getSuitFeeType())) {
return toAjax(deviceService.resetEleWithBill(order.getDeviceId(), false, bo.getTotalEle()));
}
return error("未知的订单套餐类型");
}
@Log(title = "提前结束使用智能订单", businessType = BusinessType.OTHER, operatorType = OperatorType.MOBILE)
@ApiOperation("提前结束使用智能订单")
@PutMapping("/endSmartUse")
public AjaxResult endSmartUse(@RequestBody @Validated EndUseDTO dto) {
EndUseBO bo = transactionBillConverter.toEndUseBO(dto);
if (!transactionBillValidator.isUser(bo.getOrder(), getUserId()) && !transactionBillValidator.isMch(bo.getOrder(), getUserId())) {
return error("您不是该订单的用户或商户,无法结束订单");
}
return success(transactionBillService.endUse(bo, true ));
return error("当前接口已弃用,请使用/app/bill/endUse");
// EndUseBO bo = transactionBillConverter.toEndUseBO(dto);
// if (!transactionBillValidator.isUser(bo.getOrder(), getUserId()) && !transactionBillValidator.isMch(bo.getOrder(), getUserId())) {
// return error("您不是该订单的用户或商户,无法结束订单");
// }
// return success(transactionBillService.endUse(bo, true ));
}
@ -323,11 +337,12 @@ public class AppTransactionBillController extends BaseController
@ApiOperation("提前结束使用分时段订单")
@PutMapping("/endTimingUse")
public AjaxResult endTimingUse(@RequestBody @Validated EndUseDTO dto) {
EndUseBO bo = transactionBillConverter.toEndUseBO(dto);
if (!transactionBillValidator.isUser(bo.getOrder(), getUserId()) && !transactionBillValidator.isMch(bo.getOrder(), getUserId())) {
return error("您不是该订单的用户或商户,无法结束订单");
}
return success(transactionBillService.endUse(bo, true ));
return error("当前接口已弃用,请使用/app/bill/endUse");
// EndUseBO bo = transactionBillConverter.toEndUseBO(dto);
// if (!transactionBillValidator.isUser(bo.getOrder(), getUserId()) && !transactionBillValidator.isMch(bo.getOrder(), getUserId())) {
// return error("您不是该订单的用户或商户,无法结束订单");
// }
// return success(transactionBillService.endUse(bo, true ));
}
@ApiOperation("获取订单预估金额")
@ -386,7 +401,7 @@ public class AppTransactionBillController extends BaseController
if (bill == null) {
return error("订单不存在");
}
return success(transactionBillService.rechargeDevice(bill.getBillId(), 1));
return success(transactionBillService.rechargeDevice(bill.getBillId()));
}
}

View File

@ -161,7 +161,7 @@ public class SmDeviceController extends BaseController
if (unit == null) {
return error("非法的时长单位");
}
return toAjax(deviceService.addTimeByUser(deviceId, amount * unit.getConversion(), true, "管理员手动充值时长"));
return toAjax(deviceService.addTime(deviceId, amount * unit.getConversion(), true, "管理员手动充值时长"));
}
@PreAuthorize("@ss.hasPermi('system:device:addEle')")
@ -184,7 +184,7 @@ public class SmDeviceController extends BaseController
@Log(title = "设备清空电量", businessType = BusinessType.OTHER)
@PutMapping("/{deviceId}/resetEle")
public AjaxResult resetEle(@PathVariable @ApiParam("设备id") Long deviceId) {
return toAjax(deviceService.resetEleWithBill(deviceId, true));
return toAjax(deviceService.resetEleWithBill(deviceId, true, null));
}
@ApiOperation("设备开关")

View File

@ -138,7 +138,7 @@ public class SmTransactionBillController extends BaseController
@GetMapping("/rechargeDevice/{billId}")
@Log(title = "手动设备充值", businessType = BusinessType.UPDATE)
public AjaxResult rechargeDevice(@PathVariable Long billId) {
return toAjax(transactionBillService.rechargeDevice(billId, 1));
return toAjax(transactionBillService.rechargeDevice(billId));
}
// 订单退款