结束订单、设备电量归零

This commit is contained in:
墨大叔 2024-09-06 16:16:42 +08:00
parent a39a835148
commit 15b7f77fb5
24 changed files with 302 additions and 166 deletions

View File

@ -18,7 +18,7 @@ public class ReceiveConstants {
public static final String DS_W = "W";
// 数据点ID开关状态
public static final String DS_S = "S";
// 数据点ID剩余金额
// 数据点ID剩余电量
public static final String DS_M = "M";
// 数据点ID断电方式
public static final String DS_SET = "SET";

View File

@ -76,6 +76,7 @@ public class Device extends BaseEntity
@Excel(name = "总用电量")
@ApiModelProperty("总用电量KWH")
@JsonView(JsonViewProfile.App.class)
private BigDecimal totalElectriQuantity;
/** 在线状态 */
@ -93,18 +94,21 @@ public class Device extends BaseEntity
/** 实时功率(千瓦) */
@Excel(name = "实时功率", readConverterExp = "千=瓦")
@ApiModelProperty("实时功率")
@JsonView(JsonViewProfile.App.class)
private BigDecimal realTimePower;
/** 电流A */
@Excel(name = "电流", readConverterExp = "A=")
@ApiModelProperty("电流A")
@Min(value = 0, message = "电流不允许小于0", groups = {ValidGroup.Create.class, ValidGroup.Update.class, ValidGroup.FrontUpdate.class})
@JsonView(JsonViewProfile.App.class)
private BigDecimal electricity;
/** 电压V */
@Excel(name = "电压", readConverterExp = "V=")
@ApiModelProperty("电压V")
@Min(value = 0, message = "电压不允许小于0", groups = {ValidGroup.Create.class, ValidGroup.Update.class, ValidGroup.FrontUpdate.class})
@JsonView(JsonViewProfile.App.class)
private BigDecimal voltage;
/** 用户昵称 */
@ -193,5 +197,6 @@ public class Device extends BaseEntity
private Long lockUserId;
@ApiModelProperty("剩余电量(度)")
@JsonView(JsonViewProfile.App.class)
private BigDecimal surplusEle;
}

View File

@ -301,4 +301,9 @@ public interface DeviceService
* 归零电量
*/
int resetEle(Long deviceId, boolean required);
/**
* 电量归零并关闭订单
*/
int resetEleWithBill(Long deviceId);
}

View File

@ -35,10 +35,12 @@ import com.ruoyi.ss.record.time.service.IRecordTimeService;
import com.ruoyi.ss.record.time.service.RecordTimeConverter;
import com.ruoyi.ss.store.domain.StoreVo;
import com.ruoyi.ss.store.service.StoreService;
import com.ruoyi.ss.suit.domain.enums.SuitFeeType;
import com.ruoyi.ss.timeBill.domain.TimeBillQuery;
import com.ruoyi.ss.timeBill.domain.TimeBillVO;
import com.ruoyi.ss.timeBill.service.TimeBillService;
import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus;
import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import com.ruoyi.ss.user.domain.SmUserVo;
@ -437,8 +439,11 @@ public class DeviceServiceImpl implements DeviceService
// 物联网设备归零
try {
CommandResponse res = iotService.setTime(device.getMac(), 1L, device.getModelProductId());
CommandResponse res = iotService.setTime(device.getMac(), 0L, device.getModelProductId());
ServiceUtil.assertion( !res.isSuccess(), "设备归零失败,请检查设备是否在线或联系管理员");
boolean close = iotService.close(device.getMac(), device.getModelProductId());
ServiceUtil.assertion( !close, "设备关闭失败,请检查设备是否在线或联系管理员");
} catch (Exception e) {
if (required) {
throw e;
@ -465,10 +470,6 @@ public class DeviceServiceImpl implements DeviceService
if (device == null) {
return 0;
}
// 剩余电量小于等于0不需要处理
if (device.getSurplusEle() == null || device.getSurplusEle().compareTo(BigDecimal.ZERO) <= 0) {
return 1;
}
Integer result = transactionTemplate.execute(status -> {
// 更新剩余电量
@ -502,10 +503,43 @@ public class DeviceServiceImpl implements DeviceService
@Override
public int resetEle(Long deviceId, boolean required) {
// 获取设备信息
DeviceVO device = selectSmDeviceByDeviceId(deviceId);
return resetEle(device, required);
}
@Override
public int resetEleWithBill(Long deviceId) {
if (deviceId == null) {
return 0;
}
// 拉取设备信息
pullDeviceInfo(deviceId);
DeviceVO device = selectSmDeviceByDeviceId(deviceId);
ServiceUtil.assertion(device == null, "设备不存在");
Integer result = transactionTemplate.execute(status -> {
// 关闭该设备未结束的所有订单
TransactionBillQuery query = new TransactionBillQuery();
query.setStatusList(TransactionBillStatus.canClose());
query.setDeviceId(device.getDeviceId());
query.setIsFinished(false); // 未结束的订单都会被关闭
query.setSuitFeeTypes(SuitFeeType.rechargeCountList());
List<TransactionBillVO> billList = transactionBillService.selectSmTransactionBillList(query);
int closeCount = transactionBillService.batchCloseBillByDevice(billList, false, device);
ServiceUtil.assertion(closeCount != billList.size(), "关闭订单失败");
// 发送命令
int reset = this.resetEle(device, true);
ServiceUtil.assertion(reset != 1, "设备电量归零失败");
return reset;
});
return result == null ? 0 : result;
}
@Override
public boolean addTime(Long deviceId, long seconds, boolean withIot) {
@ -799,15 +833,26 @@ public class DeviceServiceImpl implements DeviceService
public boolean resetTimeWithBill(Long deviceId) {
ServiceUtil.assertion(deviceId == null, "设备id不能为空");
LocalDateTime now = LocalDateTime.now();
// 拉取最新设备信息
pullDeviceInfo(deviceId);
// 获取设备信息
DeviceVO device = deviceMapper.selectSmDeviceByDeviceId(deviceId);
ServiceUtil.assertion(device == null || device.getDeleted(), "设备不存在");
ServiceUtil.assertion(!UserUtil.hasFrontUser(device.getUserId()), "您不是该设备的商户,无法进行该操作");
transactionTemplate.execute(status -> {
// 关闭该设备未结束的所有订单
transactionBillService.batchEndBillByDevice(deviceId);
TransactionBillQuery query = new TransactionBillQuery();
query.setStatusList(TransactionBillStatus.canClose());
query.setDeviceId(device.getDeviceId());
query.setIsFinished(false); // 未结束的订单都会被关闭
query.setSuitFeeTypes(SuitFeeType.rechargeTimeList());
List<TransactionBillVO> billList = transactionBillService.selectSmTransactionBillList(query);
int closeCount = transactionBillService.batchCloseBillByDevice(billList, false, device);
ServiceUtil.assertion(closeCount != billList.size(), "关闭订单失败");
// 发送命令
int reset = this.resetTime(device, true);
ServiceUtil.assertion(reset != 1, "归零失败");

View File

@ -54,4 +54,18 @@ public enum SuitFeeType {
public static List<String> needConfigTimeUnit() {
return asList(TIME);
}
/**
* 充值时长的类型
*/
public static List<String> rechargeTimeList() {
return asList(TIME, TIMING_TIME);
}
/**
* 充值电量的类型
*/
public static List<String> rechargeCountList() {
return asList(COUNT, TIMING_COUNT);
}
}

View File

@ -111,4 +111,7 @@ public class TransactionBillQuery extends TransactionBill {
@ApiModelProperty("结束使用电量(结束)")
private BigDecimal endSuitEndEle;
@ApiModelProperty("是否已结束")
private Boolean isFinished;
}

View File

@ -1,27 +0,0 @@
package com.ruoyi.ss.transactionBill.domain.bo;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.transactionBill.domain.dto.EndSmartUseDTO;
import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO;
import com.ruoyi.ss.user.domain.SmUserVo;
import lombok.Data;
/**
* @author wjh
* 2024/8/15
*/
@Data
public class EndSmartUseBO {
// 原参数
private EndSmartUseDTO dto;
// 订单
private TransactionBillVO order;
// 设备
private DeviceVO device;
// 操作人
private LoginUser loginUser;
}

View File

@ -1,25 +1,23 @@
package com.ruoyi.ss.transactionBill.domain.bo;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.transactionBill.domain.dto.EndTimingUseDTO;
import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO;
import lombok.Data;
import java.math.BigDecimal;
/**
* 结束分时订单BO
* @author wjh
* 2024/8/14
* 2024/9/6
*/
@Data
public class EndTimingUseBO {
public class EndUseBO {
// 总用电量蓝牙
private BigDecimal totalEle;
// 订单
private TransactionBillVO order;
// 原参数
private EndTimingUseDTO dto;
// 设备
private DeviceVO device;
}

View File

@ -1,26 +0,0 @@
package com.ruoyi.ss.transactionBill.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
* 结束使用分时订单
* @author wjh
* 2024/8/14
*/
@Data
public class EndTimingUseDTO {
@ApiModelProperty("订单ID")
@NotNull(message = "订单不允许为空")
private Long billId;
@ApiModelProperty("总用电量(仅蓝牙关闭计量订单时需要传入)")
@Min(value = 0, message = "总用电量不允许小于0")
private BigDecimal totalEle;
}

View File

@ -3,23 +3,19 @@ package com.ruoyi.ss.transactionBill.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
* @author wjh
* 2024/8/15
* 2024/9/6
*/
@Data
public class EndSmartUseDTO {
public class EndUseDTO {
@ApiModelProperty("订单ID")
@NotNull(message = "订单不允许为空")
private Long billId;
@ApiModelProperty("总用电量")
@Min(value = 0, message = "总用电量不允许小于0")
private BigDecimal totalEle;
}

View File

@ -64,4 +64,11 @@ public enum TransactionBillStatus {
public static List<String> countOfLimit() {
return asList(WITHDRAW_SUCCESS, WITHDRAW_APPROVING, WITHDRAW_FAIL, WITHDRAW_PASSED, WITHDRAW_PAYING);
}
/**
* 可以结束的状态
*/
public static List<String> canClose() {
return asList(SUCCESS, SUCCESS_DEPOSIT);
}
}

View File

@ -45,6 +45,10 @@ public class TransactionBillVO extends TransactionBill {
@JsonView(JsonViewProfile.App.class)
private Boolean isUsing;
@ApiModelProperty("是否已经结束使用")
@JsonView(JsonViewProfile.App.class)
private Boolean isFinished;
/**
* 获取套餐时长
*/

View File

@ -67,6 +67,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select
<include refid="BaseColumns"/>
if(<include refid="isUsing"/>, true, false) as is_using,
if(<include refid="isFinished"/>, true, false) as is_finished,
su.user_name as user_name,
su1.user_name as mch_name,
su1.phonenumber as mch_mobile,
@ -116,6 +117,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
)
</sql>
<sql id="isFinished">
(
(
stb.suit_end_time is not null and stb.suit_end_time &lt;= now()
)
or
(
stb.suit_fee_type in ('2', '3')
and (stb.suit_end_ele is not null and stb.suit_end_ele &lt;= sd.total_electri_quantity)
)
)
</sql>
<sql id="searchCondition">
<if test="query.userId != null "> and stb.user_id = #{query.userId}</if>
<if test="query.billNo != null and query.billNo != ''"> and stb.bill_no like concat('%', #{query.billNo}, '%')</if>
@ -156,6 +171,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and !<include refid="isUsing"/>
</if>
</if>
<if test="query.isFinished != null">
<if test="query.isFinished">
and <include refid="isFinished"/>
</if>
<if test="!query.isFinished">
and !<include refid="isFinished"/>
</if>
</if>
<if test="query.keyword != null and query.keyword != ''">
and (
sd.device_no like concat('%', #{query.keyword}, '%')

View File

@ -27,7 +27,5 @@ public interface TransactionBillConverter {
RechargePayDepositBO toRechargePayDepositBO(PayDepositDTO dto);
EndTimingUseBO toEndTimingUseBO(EndTimingUseDTO dto);
EndSmartUseBO toEndSmartUseBO(EndSmartUseDTO dto);
EndUseBO toEndUseBO(EndUseDTO dto);
}

View File

@ -1,6 +1,7 @@
package com.ruoyi.ss.transactionBill.service;
import com.ruoyi.ss.dashboard.BillCountVo;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.payBill.domain.vo.DoPayVO;
import com.ruoyi.ss.transactionBill.domain.TransactionBill;
import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery;
@ -220,7 +221,7 @@ public interface TransactionBillService
/**
* 根据设备ID批量结束订单
*/
int batchEndBillByDevice(Long deviceId);
int batchCloseBillByDevice(List<TransactionBillVO> billList, boolean withDevice, DeviceVO device);
/**
* 获取用户提现手续费信息
@ -257,16 +258,6 @@ public interface TransactionBillService
*/
DoPayVO payDeposit(RechargePayDepositBO bo);
/**
* 结束分时段订单
*/
int endTimingUse(EndTimingUseBO endTimingBO);
/**
* 提前结束智能订单
*/
int endSmartUse(EndSmartUseBO bo);
/**
* 查询未支付的分时段订单
*/
@ -283,4 +274,11 @@ public interface TransactionBillService
* @return
*/
BigDecimal selectSumOfMoney(TransactionBillQuery query);
/**
* 结束使用订单
*/
int endUse(EndUseBO bo, boolean withDevice);
}

View File

@ -1,7 +1,6 @@
package com.ruoyi.ss.transactionBill.service;
import com.ruoyi.common.core.domain.ValidateResult;
import com.ruoyi.ss.transactionBill.domain.bo.EndTimingUseBO;
import com.ruoyi.ss.transactionBill.domain.bo.RechargeBO;
import com.ruoyi.ss.transactionBill.domain.bo.RechargePayDepositBO;
import com.ruoyi.ss.transactionBill.domain.dto.RechargePayBO;

View File

@ -166,32 +166,16 @@ public class TransactionBillConverterImpl implements TransactionBillConverter {
}
@Override
public EndTimingUseBO toEndTimingUseBO(EndTimingUseDTO dto) {
public EndUseBO toEndUseBO(EndUseDTO dto) {
if (dto == null) {
return null;
}
TransactionBillVO order = transactionBillService.selectSmTransactionBillByBillId(dto.getBillId());
EndTimingUseBO bo = new EndTimingUseBO();
EndUseBO bo = new EndUseBO();
bo.setOrder(order);
bo.setDto(dto);
if (order != null) {
deviceService.pullDeviceInfo(order.getDeviceId());
bo.setDevice(deviceService.selectSmDeviceByDeviceId(order.getDeviceId()));
}
return bo;
}
@Override
public EndSmartUseBO toEndSmartUseBO(EndSmartUseDTO dto) {
if (dto == null) {
return null;
}
TransactionBillVO order = transactionBillService.selectSmTransactionBillByBillId(dto.getBillId());
EndSmartUseBO bo = new EndSmartUseBO();
bo.setOrder(order);
bo.setDto(dto);
bo.setTotalEle(dto.getTotalEle());
if (order != null) {
deviceService.pullDeviceInfo(order.getDeviceId());
bo.setDevice(deviceService.selectSmDeviceByDeviceId(order.getDeviceId()));

View File

@ -44,6 +44,7 @@ import com.ruoyi.ss.transactionBill.domain.vo.UserRechargeServiceVO;
import com.ruoyi.ss.transactionBill.domain.vo.UserWithdrawServiceVO;
import com.ruoyi.ss.transactionBill.domain.enums.*;
import com.ruoyi.ss.transactionBill.mapper.TransactionBillMapper;
import com.ruoyi.ss.transactionBill.service.TransactionBillConverter;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import com.ruoyi.ss.transactionBill.service.TransactionBillValidator;
import com.ruoyi.ss.transfer.domain.TransferVO;
@ -147,6 +148,9 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
@Autowired
private ISysConfigService sysConfigService;
@Autowired
private TransactionBillConverter transactionBillConverter;
/**
* 查询充值记录
*
@ -846,12 +850,10 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
}
}
@Override
public int endTimingUse(EndTimingUseBO bo) {
public int endTimingUse(EndUseBO bo, boolean closeDevice) {
if (bo == null) {
return 0;
}
EndTimingUseDTO dto = bo.getDto();
TransactionBillVO order = bo.getOrder();
DeviceVO device = bo.getDevice();
ServiceUtil.assertion(order == null, "订单不存在");
@ -861,7 +863,7 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
LocalDateTime endTime = LocalDateTime.now(); // 结束使用的时间
// 结束使用的电量若蓝牙传过来的值为空或者小于当前电量则使用当前电量否则使用蓝牙传输的电量
BigDecimal totalEle = this.calcTotalEle(device, dto.getTotalEle());
BigDecimal totalEle = this.calcTotalEle(device, bo.getTotalEle());
// 计算金额
BigDecimal money = this.calcTimingAmount(order, endTime, totalEle);
@ -883,7 +885,7 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
});
// 尝试关闭设备
if (result != null && result == 1) {
if (result != null && result == 1 && closeDevice) {
try {
if (SuitFeeType.TIMING_COUNT.getType().equals(order.getSuitFeeType())) {
deviceService.resetEle(device, true);
@ -924,32 +926,29 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
return totalAmount;
}
@Override
public int endSmartUse(EndSmartUseBO bo) {
public int endSmartUse(EndUseBO bo, boolean resetDevice) {
if (bo == null) {
return 0;
}
EndSmartUseDTO dto = bo.getDto();
TransactionBillVO order = bo.getOrder();
DeviceVO device = bo.getDevice();
ServiceUtil.assertion(order == null, "订单不存在");
ServiceUtil.assertion(!TransactionBillStatus.SUCCESS.getStatus().equals(order.getStatus()), "当前订单状态不允许结束");
ServiceUtil.assertion(!SuitFeeMode.SMART.getMode().equals(order.getSuitFeeMode()), "当前订单非智能收费订单,无法提前结束");
ServiceUtil.assertion(order.getIsFinished() != null && order.getIsFinished(), "当前订单已结束,无法操作");
ServiceUtil.assertion(device == null, "设备不存在");
LocalDateTime endTime = LocalDateTime.now(); // 结束使用的时间
// 结束使用的电量若蓝牙传过来的值为空或者小于当前电量则使用当前电量否则使用蓝牙传输的电量谁大用谁
BigDecimal totalEle = this.calcTotalEle(device, dto.getTotalEle());
BigDecimal totalEle = this.calcTotalEle(device, bo.getTotalEle());
// 若结束时间 > 订单结束时间 或者 结束电量 > 订单结束电量则表示已经结束使用
ServiceUtil.assertion(order.getSuitEndTime() != null && endTime.isAfter(order.getSuitEndTime()), "当前订单已结束,无法操作");
ServiceUtil.assertion(order.getSuitEndEle() != null && totalEle.compareTo(order.getSuitEndEle()) > 0, "当前订单已结束,无法操作");
ServiceUtil.assertion(order.getIsFinished() != null && order.getIsFinished(), "当前订单已结束,无法操作");
// 计算需要退款的金额
BigDecimal refundAmount = this.calcRefundAmount(order, endTime, totalEle);
Integer result = transactionTemplate.execute(status -> {
// 修改结束使用的时间
TransactionBill data = new TransactionBill();
@ -957,6 +956,7 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
data.setSuitEndEle(totalEle);
TransactionBillQuery query = new TransactionBillQuery();
query.setBillId(order.getBillId());
if (SuitFeeType.TIME.getType().equals(order.getSuitFeeType())) {
query.setStartSuitEndTime(endTime); // 计时的话需要结束时间在这之后的订单
} else if (SuitFeeType.COUNT.getType().equals(order.getSuitFeeType())) {
@ -979,8 +979,8 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
return update;
});
// 若金额 > 0.01 清零设备
if (BigDecimal.valueOf(0.01).compareTo(refundAmount) < 0) {
// 清零设备
if (resetDevice) {
try {
// 尝试设备清零时长电量
int clear = deviceService.clearTimeAndEle(device, false);
@ -1029,6 +1029,56 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
return transactionBillMapper.selectSumOfMoney(query);
}
public int endUseSingle(EndUseBO bo, boolean resetDevice) {
if (bo == null) {
return 0;
}
TransactionBillVO order = bo.getOrder();
DeviceVO device = bo.getDevice();
ServiceUtil.assertion(order == null, "订单不存在");
ServiceUtil.assertion(order.getIsFinished() != null && order.getIsFinished(), "当前订单已结束,无法操作");
ServiceUtil.assertion(!TransactionBillStatus.SUCCESS.getStatus().equals(order.getStatus()), "当前订单状态不允许结束");
ServiceUtil.assertion(device == null, "设备不存在");
LocalDateTime endTime = LocalDateTime.now(); // 结束使用的时间
// 结束使用的电量若蓝牙传过来的值为空或者小于当前电量则使用当前电量否则使用蓝牙传输的电量谁大用谁
BigDecimal totalEle = this.calcTotalEle(device, bo.getTotalEle());
Integer result = transactionTemplate.execute(status -> {
// 修改结束使用的时间
TransactionBill data = new TransactionBill();
data.setSuitEndTime(endTime);
data.setSuitEndEle(totalEle);
TransactionBillQuery query = new TransactionBillQuery();
query.setBillId(order.getBillId());
if (SuitFeeType.TIME.getType().equals(order.getSuitFeeType())) {
query.setStartSuitEndTime(endTime); // 计时的话需要结束时间在这之后的订单
} else if (SuitFeeType.COUNT.getType().equals(order.getSuitFeeType())) {
query.setStartSuitEndEle(totalEle); // 计量的话需要结束电量比这个大的订单
}
int update = this.updateByQuery(data, query);
ServiceUtil.assertion(update != 1, "修改订单信息失败");
return update;
});
// 尝试清零设备
if (result != null && result == 1 && resetDevice) {
try {
if (SuitFeeType.COUNT.getType().equals(order.getSuitFeeType())) {
deviceService.resetEle(device, true);
} else if(SuitFeeType.TIME.getType().equals(order.getSuitFeeType())){
deviceService.resetTime(device, true);
}
} catch (Exception e) {
log.error("尝试清零设备失败");
}
}
return result == null ? 0 : result;
}
private BigDecimal calcRefundAmount(TransactionBillVO order, LocalDateTime endTime, BigDecimal totalEle) {
// 智能收费时长计费
if (SuitFeeType.TIME.getType().equals(order.getSuitFeeType())) {
@ -1453,18 +1503,58 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
}
@Override
public int batchEndBillByDevice(Long deviceId) {
if (deviceId == null) {
public int batchCloseBillByDevice(List<TransactionBillVO> billList, boolean withDevice, DeviceVO device) {
if (CollectionUtils.isEmptyElement(billList)) {
return 0;
}
LocalDateTime now = LocalDateTime.now();
TransactionBillQuery query = new TransactionBillQuery();
query.setDeviceId(deviceId);
query.setStartSuitEndTime(now); // 套餐结束时间在这之后的都会被关闭
List<TransactionBillVO> billList = this.selectSmTransactionBillList(query);
EndUseBO bo = new EndUseBO();
bo.setDevice(device);
if (CollectionUtils.isNotEmptyElement(billList)) {
return transactionBillMapper.batchUpdateSuitEndTime(billList.stream().map(TransactionBill::getBillId).collect(Collectors.toList()), now);
Integer result = transactionTemplate.execute(status -> {
int sum = 0;
// 关闭订单智能订单需要退款
for (TransactionBillVO bill : billList) {
bo.setOrder(bill);
int end = this.endUse(bo, withDevice);
ServiceUtil.assertion(end != 1, "关闭订单失败");
sum += end;
}
return sum;
});
return result == null ? 0 : result;
}
return 0;
}
// 结束使用订单
@Override
public int endUse(EndUseBO bo, boolean withDevice) {
if (bo == null) {
return 0;
}
TransactionBillVO bill = bo.getOrder();
// 智能订单
if (SuitFeeMode.SMART.getMode().equals(bill.getSuitFeeMode())) {
// 单次智能
if (SuitFeeType.singleList().contains(bill.getSuitFeeType())) {
return this.endSmartUse(bo, withDevice);
}
// 分时段智能
else if (SuitFeeType.timingList().contains(bill.getSuitFeeType())){
return this.endTimingUse(bo, withDevice);
}
}
// 单次订单
else if (SuitFeeMode.SINGLE.getMode().equals(bill.getSuitFeeMode())) {
return this.endUseSingle(bo, withDevice);
}
return 0;
}

View File

@ -70,12 +70,12 @@ public class TransactionBillValidatorImpl extends BaseValidator implements Trans
// 检查用户是否有未支付的智能分时段订单
if (this.hasUnpaidSmartTimingOrder(user.getUserId())) {
return error("用户有未支付的订单,请先支付后继续");
return error("有未支付的订单,请先支付后继续");
}
// 检查用户是否有正在使用中的智能订单
if (this.hasUsingSmartOrder(user.getUserId())) {
return error("用户有正在使用中的智能订单,请结束后继续");
return error("有正在使用中的智能订单,请结束后继续");
}
// 检查设备是否符合条件
@ -92,7 +92,7 @@ public class TransactionBillValidatorImpl extends BaseValidator implements Trans
query.setDeviceId(device.getDeviceId());
List<TransactionBillVO> usingBill = transactionBillService.selectUsingBill(query);
if (CollectionUtils.isNotEmptyElement(usingBill)) {
return error("设备有正在使用中的订单,暂时无法下单");
return error("设备有正在使用中的订单,暂时无法下单");
}
// 店铺
@ -148,16 +148,16 @@ public class TransactionBillValidatorImpl extends BaseValidator implements Trans
return error("套餐收费方式已发生变化,请重新下单");
}
if (SuitFeeMode.SMART.getMode().equals(suit.getFeeMode())) {
if (device.getExpireTime() != null && device.getExpireTime().isAfter(LocalDateTime.now())) {
return error("当前设备还有剩余时长,无法选择智能收费方式下单");
}
if (DeviceOnlineStatus.ONLINE.getStatus().equals(device.getOnlineStatus())
&& device.getSurplusEle() != null
&& device.getSurplusEle().compareTo(BigDecimal.ZERO) > 0) {
return error("当前设备还有剩余电量,无法选择智能收费方式下单");
}
}
// if (SuitFeeMode.SMART.getMode().equals(suit.getFeeMode())) {
// if (device.getExpireTime() != null && device.getExpireTime().isAfter(LocalDateTime.now())) {
// return error("当前设备还有剩余时长,无法选择智能收费方式下单");
// }
// if (DeviceOnlineStatus.ONLINE.getStatus().equals(device.getOnlineStatus())
// && device.getSurplusEle() != null
// && device.getSurplusEle().compareTo(BigDecimal.ZERO) > 0) {
// return error("当前设备还有剩余电量,无法选择智能收费方式下单");
// }
// }
return success();
}

View File

@ -23,7 +23,7 @@ public class AppResetRecordController extends BaseController {
@Autowired
private ISmResetRecordService smResetRecordService;
@MchRequired
// @MchRequired
@ApiOperation("查询本人归零记录")
@GetMapping("/list")
public TableDataInfo list(SmResetRecordQuery dto) {

View File

@ -12,10 +12,6 @@ import com.ruoyi.ss.store.domain.*;
import com.ruoyi.ss.store.service.StoreService;
import com.ruoyi.ss.store.service.StoreAssembler;
import com.ruoyi.ss.store.service.StoreValidator;
import com.ruoyi.ss.storeApply.domain.enums.StoreApplyType;
import com.ruoyi.ss.storeApply.service.StoreApplyConverter;
import com.ruoyi.ss.storeApply.service.StoreApplyService;
import com.ruoyi.web.core.annotation.MchRequired;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@ -80,7 +76,7 @@ public class AppStoreController extends BaseController {
* @param storeId
* @return
*/
@MchRequired
// @MchRequired
@ApiOperation("删除店铺信息")
@DeleteMapping("/{storeId}")
public AjaxResult delete(@PathVariable Long storeId) {
@ -100,7 +96,7 @@ public class AppStoreController extends BaseController {
}
@MchRequired
// @MchRequired
@ApiOperation("调整店铺排序")
@PutMapping("/changeSort")
public AjaxResult changeSort(@RequestBody List<Store> list) {
@ -141,7 +137,7 @@ public class AppStoreController extends BaseController {
return success(store);
}
@MchRequired
// @MchRequired
@ApiOperation("商户获取店铺信息")
@GetMapping("/mch/{storeId}")
public AjaxResult getMchDetail(@PathVariable @ApiParam("店铺ID") Long storeId) {
@ -153,7 +149,7 @@ public class AppStoreController extends BaseController {
return success(store);
}
@MchRequired
// @MchRequired
@ApiOperation("切换默认店铺")
@PutMapping("/{storeId}/setDefault")
public AjaxResult setDefaultStore(@PathVariable Long storeId) {

View File

@ -12,8 +12,7 @@ import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.ss.dashboard.BillCountVo;
import com.ruoyi.ss.device.service.DeviceValidator;
import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery;
import com.ruoyi.ss.transactionBill.domain.bo.EndSmartUseBO;
import com.ruoyi.ss.transactionBill.domain.bo.EndTimingUseBO;
import com.ruoyi.ss.transactionBill.domain.bo.EndUseBO;
import com.ruoyi.ss.transactionBill.domain.dto.*;
import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillGroupBy;
@ -23,7 +22,6 @@ import com.ruoyi.ss.transactionBill.service.TransactionAssembler;
import com.ruoyi.ss.transactionBill.service.TransactionBillConverter;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import com.ruoyi.ss.transactionBill.service.TransactionBillValidator;
import com.ruoyi.ss.transactionBill.service.impl.TransactionBillServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@ -266,24 +264,35 @@ public class AppTransactionBillController extends BaseController
return success(transactionBillService.payDeposit(transactionBillConverter.toRechargePayDepositBO(dto)));
}
@ApiOperation("结束使用分时段订单")
@PutMapping("/endTimingUse")
public AjaxResult endTimingUse(@RequestBody @Validated EndTimingUseDTO dto) {
EndTimingUseBO bo = transactionBillConverter.toEndTimingUseBO(dto);
@ApiOperation("提前结束使用订单")
@PutMapping("/endUse")
public AjaxResult endUse(@RequestBody @Validated EndUseDTO dto) {
EndUseBO bo = transactionBillConverter.toEndUseBO(dto);
if (!transactionBillValidator.isUser(bo.getOrder(), getUserId()) && !transactionBillValidator.isMch(bo.getOrder(), getUserId())) {
return error("您不是该订单的用户或商户,无法结束订单");
}
return toAjax(transactionBillService.endTimingUse(bo));
return toAjax(transactionBillService.endUse(bo, true ));
}
@ApiOperation("提前结束使用智能订单")
@PutMapping("/endSmartUse")
public AjaxResult endSmartUse(@RequestBody @Validated EndSmartUseDTO dto) {
EndSmartUseBO bo = transactionBillConverter.toEndSmartUseBO(dto);
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 toAjax(transactionBillService.endSmartUse(bo));
return toAjax(transactionBillService.endUse(bo, true ));
}
@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 toAjax(transactionBillService.endUse(bo, true ));
}
@ApiOperation("获取订单预估金额")
@ -307,4 +316,5 @@ public class AppTransactionBillController extends BaseController
query.setUserId(getUserId());
return success(transactionBillService.selectUnpaidTimingBill(query));
}
}

View File

@ -162,7 +162,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.resetEle(deviceId, true));
return toAjax(deviceService.resetEleWithBill(deviceId));
}
@ApiOperation("设备开关")

View File

@ -5,9 +5,11 @@ import javax.servlet.http.HttpServletResponse;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery;
import com.ruoyi.ss.transactionBill.domain.dto.EndUseDTO;
import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO;
import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO;
import com.ruoyi.ss.transactionBill.domain.dto.WithdrawApprovalDTO;
import com.ruoyi.ss.transactionBill.service.TransactionBillConverter;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
@ -43,6 +45,9 @@ public class SmTransactionBillController extends BaseController
@Autowired
private TransactionBillService transactionBillService;
@Autowired
private TransactionBillConverter transactionBillConverter;
/**
* 查询充值记录列表
*/
@ -164,6 +169,7 @@ public class SmTransactionBillController extends BaseController
// 订单退款
@PutMapping("/refund")
@Log(title = "订单退款", businessType = BusinessType.OTHER)
@PreAuthorize("@ss.hasPermi('system:bill:refund')")
public AjaxResult refund(@RequestBody @Validated BillRefundDTO dto) {
TransactionBillVO bill = transactionBillService.selectSmTransactionBillByBillId(dto.getBillId());
@ -177,4 +183,12 @@ public class SmTransactionBillController extends BaseController
dto.setRefundReason(String.format("充值订单%s退款", bill.getBillNo()));
return toAjax(transactionBillService.refund(dto));
}
// 结束订单
@PutMapping("/close")
@Log(title = "结束订单", businessType = BusinessType.OTHER)
@PreAuthorize("@ss.hasPermi('system:bill:close')")
public AjaxResult close(@RequestBody @Validated EndUseDTO dto) {
return success(transactionBillService.endUse(transactionBillConverter.toEndUseBO(dto), true));
}
}