package com.ruoyi.account.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.account.api.dto.ChargingCardAllocateDTO; import com.ruoyi.account.api.dto.ChargingCardAuthDTO; import com.ruoyi.account.api.dto.ChargingCardDeductDTO; import com.ruoyi.account.api.dto.ChargingCardExcelDTO; import com.ruoyi.account.api.dto.ChargingCardQueryDTO; import com.ruoyi.account.api.dto.ChargingCardSaveDTO; import com.ruoyi.account.api.dto.ChargingCardStatusDTO; import com.ruoyi.account.api.model.TChargingCard; import com.ruoyi.account.api.vo.ChargingCardAllocateVO; import com.ruoyi.account.api.vo.ChargingCardDeductVO; import java.math.BigDecimal; import java.util.List; public interface TChargingCardService extends IService { IPage selectCardPage(ChargingCardQueryDTO query); boolean saveCard(ChargingCardSaveDTO dto); boolean updateCard(ChargingCardSaveDTO dto); boolean deleteCards(List ids); /** * 批量解绑车队:仅清空车队归属(fleet_id 置空),公司、余额、状态等不受影响; * 未绑定车队的选中记录忽略不计,返回实际解绑数量 */ int unbindFleet(List ids); boolean updateStatus(ChargingCardStatusDTO dto); /** * 额度分配概览:公司可分配余额(available_balance)与总账户余额(累计充值到账)。 * 仅分配模式(account_mode=2)的公司可执行额度分配。 * * @param companyId 公司ID * @return 概览信息;公司不存在时抛出业务异常 */ ChargingCardAllocateVO getAllocateOverview(Integer companyId); /** * 卡片额度分配(公司可用余额 → 卡片余额)。 * 校验公司为启用且分配模式、卡片归属该公司且未在充电,禁止透支; * 每张卡片写入余额变更流水,失败时回滚并退还公司已扣金额。 * * @param dto 分配参数(公司、卡片明细、备注) * @return 分配后的公司概览(可分配余额为最新值) */ ChargingCardAllocateVO allocateQuota(ChargingCardAllocateDTO dto); List selectExportList(ChargingCardQueryDTO query); String importCards(List cards); /** * 刷卡启动鉴权(内部接口)。 * 条件密码校验(V0.2 定稿):卡片配置了密码时校验设备上报密码;未配置密码时不校验。 * * @param dto 卡号与设备上报密码 * @return 鉴权通过返回卡片实体(不包含密码密文);失败抛出 ServiceException 携带原因 */ TChargingCard verifyCardForCharging(ChargingCardAuthDTO dto); /** * 锁定卡片为充电中(刷卡订单创建成功后调用)。同卡已有进行中订单时返回 false。 */ boolean lockCardForCharging(Long cardId, String orderCode); /** * 解锁卡片(订单终态后调用)。带订单号比对,幂等:已解锁或订单号不匹配时返回 false。 */ boolean unlockCardForCharging(Long cardId, String orderCode); /** * 刷卡订单最终结算扣款(内部接口)。 * 幂等(订单号为幂等键)+ 允许扣成负余额(V0.2 定稿)。 * * @return 扣款结果;duplicated=true 表示该订单此前已扣款,本次未重复扣款 */ ChargingCardDeductVO deductBalanceForCharging(ChargingCardDeductDTO dto); /** * 批量查询已经成功写入充电扣款流水的订单号。 */ List listDeductedOrderCodes(List orderCodes); /** * 锁定卡片账户余额(刷卡充电申请,分配模式实扣冻结:余额立即扣减并计入锁定金额)。 * * @param cardId 卡片ID * @param amount 锁定金额(大于0) * @return 锁定后剩余可用余额;余额不足时抛出业务异常 */ BigDecimal lockBalance(Long cardId, BigDecimal amount); /** * 结算卡片账户余额(解锁锁定额并按实际消费扣减,允许扣成负数)。 * 与旧扣款接口共用「订单号+change_type=3」唯一键幂等;lockedAmount 为空时等价于仅按实扣金额扣减, * 兼容历史无锁定额订单。 * * @return 结算结果;duplicated=true 表示该订单此前已结算,本次未重复结算 */ ChargingCardDeductVO settleBalanceForCharging(ChargingCardDeductDTO dto); /** * 释放卡片锁定金额(未产生消费/订单回滚时使用)。 * * @param cardId 卡片ID * @param amount 释放金额(大于0) * @return 释放后可用余额 */ BigDecimal unlockBalance(Long cardId, BigDecimal amount); /** * 按公司查询未删除的卡片列表(公司详情-充电用户信息聚合使用) */ List listByCompany(Integer companyId); }