|
|
@@ -36,6 +36,8 @@ import com.zsElectric.boot.business.model.vo.AppletStationPriceListVO;
|
|
|
import com.zsElectric.boot.business.model.vo.BannerInfoVO;
|
|
|
import com.zsElectric.boot.business.model.vo.StationInfoMapVO;
|
|
|
import com.zsElectric.boot.business.model.vo.StationInfoVO;
|
|
|
+import com.zsElectric.boot.business.model.vo.applet.AppChargingCostVO;
|
|
|
+import com.zsElectric.boot.business.model.vo.applet.AppStationSearchVO;
|
|
|
import com.zsElectric.boot.business.model.vo.applet.AppletChargingCostVO;
|
|
|
import com.zsElectric.boot.business.model.vo.applet.AppletConnectorDetailVO;
|
|
|
import com.zsElectric.boot.business.model.vo.applet.AppletStationSearchVO;
|
|
|
@@ -668,7 +670,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public AppletChargingCostVO getCurrentChargingCost() {
|
|
|
+ public AppChargingCostVO getCurrentChargingCost() {
|
|
|
// 获取当前登录用户ID
|
|
|
Long userId = SecurityUtils.getUserId();
|
|
|
if (userId == null) {
|
|
|
@@ -679,7 +681,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public List<AppletStationSearchVO> searchStations(String keyword, BigDecimal longitude, BigDecimal latitude) {
|
|
|
+ public List<AppStationSearchVO> searchStations(String keyword, BigDecimal longitude, BigDecimal latitude) {
|
|
|
// 关键词为空或空字符串,返回空列表
|
|
|
if (keyword == null || keyword.trim().isEmpty()) {
|
|
|
return new ArrayList<>();
|
|
|
@@ -693,10 +695,10 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
public AppletConnectorDetailVO getConnectorDetail(Long connectorId) {
|
|
|
// 获取当前登录用户ID
|
|
|
Long userId = SecurityUtils.getUserId();
|
|
|
-
|
|
|
+
|
|
|
// 获取当前时间(HHmmss格式)
|
|
|
String currentTime = LocalTime.now().format(TIME_FORMATTER);
|
|
|
-
|
|
|
+
|
|
|
// 查询用户余额
|
|
|
BigDecimal userBalance = null;
|
|
|
if (userId != null) {
|
|
|
@@ -709,7 +711,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
userBalance = userAccount.getBalance();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 查询新用户优惠金额(仅当用户为新用户时)
|
|
|
BigDecimal newUserDiscount = null;
|
|
|
if (userId != null) {
|
|
|
@@ -719,7 +721,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
.eq(ChargeOrderInfo::getUserId, userId)
|
|
|
.eq(ChargeOrderInfo::getIsDeleted, 0)
|
|
|
);
|
|
|
-
|
|
|
+
|
|
|
// 如果是新用户(没有订单),查询新用户首单优惠金额
|
|
|
if (orderCount == 0) {
|
|
|
// 查询c_discounts_activity表,type=1(新用户首单立减)且status=1(启用)的数据
|
|
|
@@ -729,28 +731,28 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
.eq(DiscountsActivity::getStatus, 1) // 1-启用
|
|
|
.eq(DiscountsActivity::getIsDeleted, 0)
|
|
|
);
|
|
|
-
|
|
|
+
|
|
|
// 计算所有启用的新用户优惠金额总和
|
|
|
if (!discountActivities.isEmpty()) {
|
|
|
newUserDiscount = discountActivities.stream()
|
|
|
.map(DiscountsActivity::getDiscount)
|
|
|
.filter(discount -> discount != null)
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
-
|
|
|
+
|
|
|
log.info("新用户首单优惠金额 - userId: {}, discount: {}", userId, newUserDiscount);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 调用Mapper方法,一次SQL查询获取所有信息
|
|
|
AppletConnectorDetailVO result = thirdPartyConnectorInfoMapper.selectConnectorDetailById(
|
|
|
connectorId, userId, currentTime, userBalance, newUserDiscount
|
|
|
);
|
|
|
-
|
|
|
+
|
|
|
if (result == null) {
|
|
|
log.warn("充电接口不存在,connectorId: {}", connectorId);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
@@ -762,7 +764,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
log.warn("未登录用户,无法计算可用充电金额");
|
|
|
return BigDecimal.ZERO;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 1. 查询当前用户余额
|
|
|
UserAccount userAccount = userAccountMapper.selectOne(
|
|
|
new LambdaQueryWrapper<UserAccount>()
|
|
|
@@ -774,7 +776,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
return BigDecimal.ZERO;
|
|
|
}
|
|
|
BigDecimal userBalance = userAccount.getBalance();
|
|
|
-
|
|
|
+
|
|
|
// 2. 从字典表查询安全价(safety_fee)
|
|
|
DictItem safetyFeeItem = dictItemMapper.selectOne(
|
|
|
new LambdaQueryWrapper<DictItem>()
|
|
|
@@ -782,24 +784,24 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
.eq(DictItem::getStatus, 1)
|
|
|
.last("LIMIT 1")
|
|
|
);
|
|
|
- BigDecimal safetyFee = safetyFeeItem != null && safetyFeeItem.getValue() != null
|
|
|
- ? new BigDecimal(safetyFeeItem.getValue())
|
|
|
+ BigDecimal safetyFee = safetyFeeItem != null && safetyFeeItem.getValue() != null
|
|
|
+ ? new BigDecimal(safetyFeeItem.getValue())
|
|
|
: BigDecimal.ZERO;
|
|
|
-
|
|
|
+
|
|
|
// 计算扣除安全价后的余额
|
|
|
BigDecimal balanceAfterSafety = userBalance.subtract(safetyFee);
|
|
|
if (balanceAfterSafety.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
log.info("用户余额不足 - userId: {}, balance: {}, safetyFee: {}", userId, userBalance, safetyFee);
|
|
|
return BigDecimal.ZERO;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 3. 查询充电接口、设备、站点信息
|
|
|
ThirdPartyConnectorInfo connectorInfo = thirdPartyConnectorInfoMapper.selectById(connectorId);
|
|
|
if (connectorInfo == null) {
|
|
|
log.warn("充电接口不存在 - connectorId: {}", connectorId);
|
|
|
return BigDecimal.ZERO;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
ThirdPartyEquipmentInfo equipmentInfo = thirdPartyEquipmentInfoMapper.selectOne(
|
|
|
new LambdaQueryWrapper<ThirdPartyEquipmentInfo>()
|
|
|
.eq(ThirdPartyEquipmentInfo::getEquipmentId, connectorInfo.getEquipmentId())
|
|
|
@@ -810,7 +812,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
log.warn("设备信息不存在 - equipmentId: {}", connectorInfo.getEquipmentId());
|
|
|
return BigDecimal.ZERO;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectOne(
|
|
|
new LambdaQueryWrapper<ThirdPartyStationInfo>()
|
|
|
.eq(ThirdPartyStationInfo::getStationId, equipmentInfo.getStationId())
|
|
|
@@ -821,7 +823,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
log.warn("站点信息不存在 - stationId: {}", equipmentInfo.getStationId());
|
|
|
return BigDecimal.ZERO;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 4. 查询价格策略
|
|
|
ThirdPartyEquipmentPricePolicy pricePolicy = thirdPartyEquipmentPricePolicyMapper.selectOne(
|
|
|
new LambdaQueryWrapper<ThirdPartyEquipmentPricePolicy>()
|
|
|
@@ -833,7 +835,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
log.warn("价格策略不存在 - connectorId: {}", connectorInfo.getConnectorId());
|
|
|
return BigDecimal.ZERO;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 5. 查询所有时段的价格信息(按开始时间排序)
|
|
|
List<ThirdPartyPolicyInfo> policyInfoList = thirdPartyPolicyInfoMapper.selectList(
|
|
|
new LambdaQueryWrapper<ThirdPartyPolicyInfo>()
|
|
|
@@ -845,7 +847,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
log.warn("价格策略明细不存在 - pricePolicyId: {}", pricePolicy.getId());
|
|
|
return BigDecimal.ZERO;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 6. 查询用户是否为企业用户
|
|
|
UserFirm userFirm = userFirmMapper.selectOne(
|
|
|
new LambdaQueryWrapper<UserFirm>()
|
|
|
@@ -853,26 +855,26 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
.eq(UserFirm::getIsDeleted, 0)
|
|
|
.last("LIMIT 1")
|
|
|
);
|
|
|
-
|
|
|
+
|
|
|
// 7. 跨时段计算可用充电金额
|
|
|
// 公式:可用余额 = 当前用户余额 - 安全价 - [(度数 × 运营费) + (度数 × 增值费用)]
|
|
|
// 其中:度数 = (余额 - 安全价) / (电费 + 服务费)
|
|
|
-
|
|
|
+
|
|
|
BigDecimal remainingBalance = balanceAfterSafety; // 剩余可用余额(用于计算度数)
|
|
|
BigDecimal totalOpFeeCost = BigDecimal.ZERO; // 总运营费
|
|
|
BigDecimal totalValueAddedCost = BigDecimal.ZERO; // 总增值费用
|
|
|
-
|
|
|
+
|
|
|
// 遍历每个时段,计算在该时段能充多少度电及对应的费用
|
|
|
for (ThirdPartyPolicyInfo policyInfo : policyInfoList) {
|
|
|
// 获取电费、服务费
|
|
|
BigDecimal elecPrice = policyInfo.getElecPrice() != null ? policyInfo.getElecPrice() : BigDecimal.ZERO;
|
|
|
BigDecimal servicePrice = policyInfo.getServicePrice() != null ? policyInfo.getServicePrice() : BigDecimal.ZERO;
|
|
|
BigDecimal basePrice = elecPrice.add(servicePrice); // 基础价格 = 电费 + 服务费
|
|
|
-
|
|
|
+
|
|
|
if (basePrice.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
continue; // 跳过基础价格为0的时段
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 查询该时段的运营费
|
|
|
PolicyFee policyFee;
|
|
|
if (userFirm != null) {
|
|
|
@@ -895,11 +897,11 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
.last("LIMIT 1")
|
|
|
);
|
|
|
}
|
|
|
-
|
|
|
- BigDecimal opFee = (policyFee != null && policyFee.getOpFee() != null)
|
|
|
- ? policyFee.getOpFee()
|
|
|
+
|
|
|
+ BigDecimal opFee = (policyFee != null && policyFee.getOpFee() != null)
|
|
|
+ ? policyFee.getOpFee()
|
|
|
: BigDecimal.ZERO;
|
|
|
-
|
|
|
+
|
|
|
// 查询增值费用
|
|
|
BigDecimal valueAddedFee = BigDecimal.ZERO;
|
|
|
if (policyInfo.getPeriodFlag() != null) {
|
|
|
@@ -910,7 +912,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
case 3: periodLabel = "平"; break;
|
|
|
case 4: periodLabel = "谷"; break;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (!periodLabel.isEmpty()) {
|
|
|
DictItem valueAddedItem = dictItemMapper.selectOne(
|
|
|
new LambdaQueryWrapper<DictItem>()
|
|
|
@@ -924,53 +926,53 @@ public class AppletHomeServiceImpl implements AppletHomeService {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 计算在当前时段能充多少度电(使用剩余余额)
|
|
|
// 度数 = 剩余余额 / (电费 + 服务费)
|
|
|
BigDecimal kwh = remainingBalance.divide(basePrice, 4, RoundingMode.HALF_UP);
|
|
|
-
|
|
|
+
|
|
|
// 如果剩余余额不足以充电,结束计算
|
|
|
if (kwh.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 计算该时段的运营费和增值费用
|
|
|
BigDecimal periodOpFeeCost = kwh.multiply(opFee);
|
|
|
BigDecimal periodValueAddedCost = kwh.multiply(valueAddedFee);
|
|
|
-
|
|
|
+
|
|
|
totalOpFeeCost = totalOpFeeCost.add(periodOpFeeCost);
|
|
|
totalValueAddedCost = totalValueAddedCost.add(periodValueAddedCost);
|
|
|
-
|
|
|
+
|
|
|
// 更新剩余余额(减去当前时段的所有费用)
|
|
|
// 当前时段总费用 = (电费 + 服务费) * 度数 + 运营费 + 增值费用
|
|
|
BigDecimal periodBaseCost = kwh.multiply(basePrice);
|
|
|
BigDecimal periodTotalCost = periodBaseCost.add(periodOpFeeCost).add(periodValueAddedCost);
|
|
|
remainingBalance = remainingBalance.subtract(periodTotalCost);
|
|
|
-
|
|
|
+
|
|
|
log.debug("时段计算 - startTime: {}, 电费: {}, 服务费: {}, 运营费: {}, 增值费: {}, 度数: {}, 该时段费用: {}, 剩余余额: {}",
|
|
|
policyInfo.getStartTime(), elecPrice, servicePrice, opFee, valueAddedFee, kwh, periodTotalCost, remainingBalance);
|
|
|
-
|
|
|
+
|
|
|
// 如果剩余余额小于等于0,结束计算
|
|
|
if (remainingBalance.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 8. 计算最终可用余额
|
|
|
BigDecimal availableAmount = userBalance.subtract(safetyFee).subtract(totalOpFeeCost).subtract(totalValueAddedCost);
|
|
|
-
|
|
|
+
|
|
|
// 确保不为负数
|
|
|
if (availableAmount.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
availableAmount = BigDecimal.ZERO;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 保留 2 位小数
|
|
|
availableAmount = availableAmount.setScale(2, RoundingMode.HALF_UP);
|
|
|
-
|
|
|
+
|
|
|
log.info("可用充电金额计算完成 - userId: {}, connectorId: {}, userBalance: {}, safetyFee: {}, " +
|
|
|
"totalOpFeeCost: {}, totalValueAddedCost: {}, availableAmount: {}",
|
|
|
userId, connectorId, userBalance, safetyFee, totalOpFeeCost, totalValueAddedCost, availableAmount);
|
|
|
-
|
|
|
+
|
|
|
return availableAmount;
|
|
|
}
|
|
|
|