From 69d02ff08d788f326a5429d71b753a91066649aff202692147e4271ea4b3b94b Mon Sep 17 00:00:00 2001 From: yanglei Date: Mon, 20 Oct 2025 16:56:08 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=80=E6=AC=BE=E6=9C=8D=E5=8A=A1=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/service/EbikeRefundService.java | 118 +++++ .../service/impl/EbikeRefundServiceImpl.java | 443 ++++++++++++++++++ 2 files changed, 561 insertions(+) create mode 100644 ebike-payment/src/main/java/com/cdzy/payment/service/EbikeRefundService.java create mode 100644 ebike-payment/src/main/java/com/cdzy/payment/service/impl/EbikeRefundServiceImpl.java diff --git a/ebike-payment/src/main/java/com/cdzy/payment/service/EbikeRefundService.java b/ebike-payment/src/main/java/com/cdzy/payment/service/EbikeRefundService.java new file mode 100644 index 0000000..e96cdf0 --- /dev/null +++ b/ebike-payment/src/main/java/com/cdzy/payment/service/EbikeRefundService.java @@ -0,0 +1,118 @@ +package com.cdzy.payment.service; + +import com.cdzy.payment.model.dto.RefundQueryDto; +import com.cdzy.payment.model.dto.UserQueryDto; +import com.cdzy.payment.model.entity.EbikeRefund; +import com.cdzy.payment.model.vo.*; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.service.IService; +import com.wechat.pay.java.service.refund.model.Refund; + +import java.util.List; + +/** + * 用户订单退款记录 服务层。 + * + * @author: yanglei + * @since: 2025-10-17 09:18 + */ + +public interface EbikeRefundService extends IService { + + /** + * 保存退款记录 + * + * @param ebikeRefund 退款结果 + * @return 保存成功返回主键id,否则返回null + */ + Boolean saveRefundResult(EbikeRefund ebikeRefund); + + /** + * 查询未成功退款订单 + * + * @param duration 订单创建时间超过duration分钟,单位分钟 + * @return 未成功退款订单列表 + */ + List getNoSuccessRefundOrderByDuration(int duration); + + /** + * 根据订单id查询退款记录 + * + * @param orderId 订单id + * @return + */ + EbikeRefund getByOrderId(String orderId); + + /** + * 更新退款状态 + * + * @param refund 退款结果 + * @return 更新成功返回true,否则返回false + */ + Boolean updateRefundStatus(Refund refund); + + /** + * 获取申请中的退款列表 + * + * @param refundDto 查询条件 + * @return 退款列表 + */ + Page getApplyingList(RefundQueryDto refundDto); + + /** + * 获取处理中的退款列表 + * + * @param refundDto 查询条件 + * @return 退款列表 + */ + Page getProcessingList(RefundQueryDto refundDto); + + /** + * 获取已退款的退款列表 + * + * @param refundDto 查询条件 + * @return 退款列表 + */ + Page getProcessedList(RefundQueryDto refundDto); + + /** + * 获取已驳回的退款列表 + * + * @param refundDto 查询条件 + * @return 退款列表 + */ + Page getClosedList(RefundQueryDto refundDto); + + /** + * 退款订单详情 + * + * @param refundId 退款id + * @return 退款详情 + */ + RefundOrderDetailVo getRefundOrderDetail(Long refundId); + + /** + * 退款用户申请交易记录 + * + * @param userQueryDto + * @return + */ + Page queryRefundTradeRecordById(UserQueryDto userQueryDto); + + /** + * 退款用户申请用户退款记录 + * + * @param userQueryDto + * @return + */ + Page queryRefundRefundRecordById(UserQueryDto userQueryDto); + + /** + * 退款用户订单记录 + * + * @param userQueryDto 查询条件 + * @return 用户订单列表 + */ + Page getRefundOrderRecords(UserQueryDto userQueryDto); + +} diff --git a/ebike-payment/src/main/java/com/cdzy/payment/service/impl/EbikeRefundServiceImpl.java b/ebike-payment/src/main/java/com/cdzy/payment/service/impl/EbikeRefundServiceImpl.java new file mode 100644 index 0000000..f5c8e2a --- /dev/null +++ b/ebike-payment/src/main/java/com/cdzy/payment/service/impl/EbikeRefundServiceImpl.java @@ -0,0 +1,443 @@ +package com.cdzy.payment.service.impl; + +import com.cdzy.common.enums.GlobalConstants; +import com.cdzy.payment.enums.RefundStatus; +import com.cdzy.payment.mapper.EbikeRefundMapper; +import com.cdzy.payment.model.dto.RefundQueryDto; +import com.cdzy.payment.model.dto.UserQueryDto; +import com.cdzy.payment.model.entity.EbikeRefund; +import com.cdzy.payment.model.vo.*; +import com.cdzy.payment.service.EbikeRefundService; +import com.cdzy.payment.utils.StringUtils; +import com.ebike.feign.clients.UserFeignClient; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.query.QueryMethods; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.wechat.pay.java.service.refund.model.Refund; +import com.wechat.pay.java.service.refund.model.Status; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; + +import static com.cdzy.payment.model.entity.table.EbikeFaultReportTableDef.EBIKE_FAULT_REPORT; +import static com.cdzy.payment.model.entity.table.EbikeOrderTransactionTableDef.EBIKE_ORDER_TRANSACTION; +import static com.cdzy.payment.model.entity.table.EbikePaymentTableDef.EBIKE_PAYMENT; +import static com.cdzy.payment.model.entity.table.EbikeRefundTableDef.EBIKE_REFUND; +import static com.cdzy.payment.model.entity.table.EbikeUserTableDef.EBIKE_USER; +import static com.mybatisflex.core.constant.FuncName.*; + +/** + * 用户订单退款记录 服务层实现 + * + * @author: yanglei + * @since: 2025-10-17 09:19 + */ +@Slf4j +@Service +public class EbikeRefundServiceImpl extends ServiceImpl implements EbikeRefundService { + + @Resource + private UserFeignClient userFeignClient; + + @Override + public Boolean saveRefundResult(EbikeRefund ebikeRefund) { + boolean r = save(ebikeRefund); + // 同步发起退款 + if (r) { + userFeignClient.refundApply(String.valueOf(ebikeRefund.getOrderId())); + } + return r; + } + + @Override + public List getNoSuccessRefundOrderByDuration(int duration) { + // trade_state 等于 PROCESSING正在退款中的, 并且创建时间超过duration分钟的订单 + String timeFilter = String.format("%s(%s, %s(%s))>=%s()", ADDTIME, EBIKE_REFUND.CREATE_TIME.getName(), SEC_TO_TIME + , duration * 60, NOW); + QueryWrapper query = QueryWrapper.create() + .where(String.valueOf(EBIKE_REFUND.REFUND_STATUS), RefundStatus.PROCESSED) + .and(timeFilter); + return list(query); + } + + @Override + public EbikeRefund getByOrderId(String orderId) { + // create_time到排序,取最新的一条 + QueryWrapper query = QueryWrapper.create() + .where(EBIKE_REFUND.ORDER_ID.eq(orderId)) + .orderBy(EBIKE_REFUND.CREATE_TIME.desc()); + return getOne(query); + } + + /** + * 通过退款订单号查询退款记录 + * + * @param refundOrderId 退款订单号 + * @return 退款记录 + */ + private EbikeRefund getByRefundOrderId(String refundOrderId) { + // create_time到排序,取最新的一条 + QueryWrapper query = QueryWrapper.create() + .where(EBIKE_REFUND.REFUND_ORDER.eq(refundOrderId)) + .orderBy(EBIKE_REFUND.CREATE_TIME.desc()); + return getOne(query); + } + + @Override + public Boolean updateRefundStatus(Refund refund) { + EbikeRefund ebikeRefund = getByRefundOrderId(refund.getOutRefundNo()); + ebikeRefund.setRefundStatus(refund.getStatus().ordinal()); + if (Status.SUCCESS.equals(refund.getStatus())) { + String refundTime = refund.getSuccessTime(); + ebikeRefund.setRefundTime(StringUtils.toLocalDatetime(refundTime)); + // 转换为BigDecimal,避免精度损失 + BigDecimal refundAmount = calculateRefundAmount(refund); + ebikeRefund.setRefund(refundAmount); + } + String orderId = String.valueOf(refund.getOutTradeNo()); + // 更新订单退款状态 + switch (refund.getStatus()) { + case PROCESSING, CLOSED -> userFeignClient.refund(orderId); + case SUCCESS -> userFeignClient.doneRefund(orderId); + case ABNORMAL -> userFeignClient.failRefund(orderId); + } + return updateById(ebikeRefund); + } + + /** + * 根据车辆编码获取车辆运营区域 + * + * @param bikeCode 车辆编码 + * @return 运营区域 + */ + // todo + private String getOperationArea(String bikeCode) { +// if (bikeCode == null || bikeCode.isEmpty()) +// return null; +// JsonResult bikeInfo = maintenanceFeignClient.getBikeBaseInfoByCode(bikeCode); +// if (bikeInfo.getCode() == 200) { +// EbikeBikeBaseInfo bikeBaseInfo = JSON.parseObject(JSON.toJSONString(bikeInfo.getData()), EbikeBikeBaseInfo.class); +// JsonResult areaInfo = operateFeignClient.getOperationById(Long.valueOf(bikeBaseInfo.getReginId())); +// if (areaInfo.getCode() == 200) { +// FeignEbikeRegionDto regionDto = JSON.parseObject(JSON.toJSONString(areaInfo.getData()), FeignEbikeRegionDto.class); +// return regionDto.getOperationRegionName(); +// } +// } + return null; + } + + @Override + public Page getApplyingList(RefundQueryDto refundDto) { + QueryWrapper query = QueryWrapper.create() + .select(EBIKE_REFUND.REFUND_ID.as("refund_id"), + EBIKE_REFUND.CREATE_TIME.as("apply_time"), + EBIKE_USER.MOBILE.as("mobile"), + EBIKE_REFUND.ORDER_ID.as("order_id"), + EBIKE_REFUND.REFUND_APPLY.as("apply_refund_amount"), + EBIKE_PAYMENT.TOTAL.as("actual_pay_amount"), + EBIKE_PAYMENT.PAYMENT_METHOD.as("payment_method"), + EBIKE_PAYMENT.PAYMENT_TIME.as("payment_time"), + EBIKE_REFUND.REASON.as("apply_reason"), + EBIKE_REFUND.SOURCE.as("source"), + EBIKE_USER.NICKNAME.as("username"), + EBIKE_ORDER_TRANSACTION.BIKE_CODE.as("bike_code"), + EBIKE_ORDER_TRANSACTION.START_TIME.as("start_time"), + EBIKE_ORDER_TRANSACTION.END_TIME.as("end_time"), + EBIKE_ORDER_TRANSACTION.RIDE_POINT, + EBIKE_ORDER_TRANSACTION.RETURN_POINT + ) + .leftJoin(EBIKE_PAYMENT).on(EBIKE_PAYMENT.ORDER_ID.eq(EBIKE_REFUND.ORDER_ID)) + .leftJoin(EBIKE_USER).on(EBIKE_USER.USER_ID.eq(EBIKE_PAYMENT.USER_ID)) + .leftJoin(EBIKE_ORDER_TRANSACTION).on(EBIKE_ORDER_TRANSACTION.ORDER_ID.eq(EBIKE_REFUND.ORDER_ID)) + .where(EBIKE_REFUND.PROCESS_STATUS.eq(String.valueOf(refundDto.getProcessStatus()))); + + // 查询条件 + buildQueryConditions(query, refundDto); + + Page page = refundDto.getPageParam().getPage(); + Page list = pageAs(page, query, ApplyRefundVo.class); + + list.getRecords().forEach(item -> item.setOperationArea(getOperationArea(item.getBikeCode()))); + return list; + } + + @Override + public Page getProcessingList(RefundQueryDto refundDto) { + QueryWrapper query = QueryWrapper.create() + .select(EBIKE_REFUND.REFUND_ID.as("refund_id"), + EBIKE_REFUND.CREATE_TIME.as("apply_time"), + EBIKE_USER.MOBILE.as("mobile"), + EBIKE_REFUND.ORDER_ID.as("order_id"), + EBIKE_REFUND.REFUND_APPLY.as("apply_refund_amount"), + EBIKE_PAYMENT.TOTAL.as("actual_pay_amount"), + EBIKE_PAYMENT.PAYMENT_METHOD.as("payment_method"), + EBIKE_REFUND.REFUND.as("refund_amount"), + EBIKE_REFUND.REFUND_METHOD.as("refund_method"), + EBIKE_PAYMENT.PAYMENT_TIME.as("payment_time"), + EBIKE_REFUND.REASON.as("apply_reason"), + EBIKE_REFUND.SOURCE.as("source"), + EBIKE_USER.NICKNAME.as("username"), + EBIKE_ORDER_TRANSACTION.BIKE_CODE.as("bike_code"), + EBIKE_ORDER_TRANSACTION.START_TIME.as("start_time"), + EBIKE_ORDER_TRANSACTION.END_TIME.as("end_time"), + EBIKE_ORDER_TRANSACTION.RIDE_POINT, + EBIKE_ORDER_TRANSACTION.RETURN_POINT + ) + .leftJoin(EBIKE_PAYMENT).on(EBIKE_PAYMENT.ORDER_ID.eq(EBIKE_REFUND.ORDER_ID)) + .leftJoin(EBIKE_USER).on(EBIKE_USER.USER_ID.eq(EBIKE_PAYMENT.USER_ID)) + .leftJoin(EBIKE_ORDER_TRANSACTION).on(EBIKE_ORDER_TRANSACTION.ORDER_ID.eq(EBIKE_REFUND.ORDER_ID)) + .where(EBIKE_REFUND.PROCESS_STATUS.eq(String.valueOf(refundDto.getProcessStatus()))); + // 查询条件 + buildQueryConditions(query, refundDto); + Page page = refundDto.getPageParam().getPage(); + Page list = pageAs(page, query, HandleRefundVo.class); + list.getRecords().forEach(item -> item.setOperationArea(getOperationArea(item.getBikeCode()))); + return list; + } + + @Override + public Page getProcessedList(RefundQueryDto refundDto) { + QueryWrapper query = QueryWrapper.create() + .select(EBIKE_REFUND.REFUND_ID.as("refund_id"), + EBIKE_REFUND.CREATE_TIME.as("apply_time"), + EBIKE_USER.MOBILE.as("mobile"), + EBIKE_REFUND.ORDER_ID.as("order_id"), + EBIKE_PAYMENT.TOTAL.as("actual_pay_amount"), + EBIKE_REFUND.REFUND_STATUS.as("arrived_status"), + EBIKE_REFUND.REFUND_TIME.as("arrived_time"), + EBIKE_REFUND.REFUND_TRANSACTION_ID.as("trade_serial_number"), + EBIKE_PAYMENT.PAYMENT_METHOD.as("payment_method"), + EBIKE_REFUND.REFUND.as("refund_amount"), + EBIKE_REFUND.REFUND_METHOD.as("refund_method"), + EBIKE_PAYMENT.PAYMENT_TIME.as("payment_time"), + EBIKE_REFUND.REASON.as("apply_reason"), + EBIKE_REFUND.SOURCE.as("source"), + EBIKE_USER.NICKNAME.as("username"), + EBIKE_ORDER_TRANSACTION.BIKE_CODE.as("bike_code"), + EBIKE_ORDER_TRANSACTION.START_TIME.as("start_time"), + EBIKE_ORDER_TRANSACTION.END_TIME.as("end_time"), + EBIKE_ORDER_TRANSACTION.RIDE_POINT, + EBIKE_ORDER_TRANSACTION.RETURN_POINT + ) + .leftJoin(EBIKE_PAYMENT).on(EBIKE_PAYMENT.ORDER_ID.eq(EBIKE_REFUND.ORDER_ID)) + .leftJoin(EBIKE_USER).on(EBIKE_USER.USER_ID.eq(EBIKE_PAYMENT.USER_ID)) + .leftJoin(EBIKE_ORDER_TRANSACTION).on(EBIKE_ORDER_TRANSACTION.ORDER_ID.eq(EBIKE_REFUND.ORDER_ID)) + .where(EBIKE_REFUND.PROCESS_STATUS.eq(String.valueOf(refundDto.getProcessStatus()))); + + // 查询条件 + buildQueryConditions(query, refundDto); + Page page = refundDto.getPageParam().getPage(); + Page list = pageAs(page, query, ProcessedRefundVo.class); + list.getRecords().forEach(item -> item.setOperationArea(getOperationArea(item.getBikeCode()))); + return list; + } + + @Override + public Page getClosedList(RefundQueryDto refundDto) { + QueryWrapper query = QueryWrapper.create() + .select(EBIKE_REFUND.REFUND_ID.as("refund_id"), + EBIKE_REFUND.CREATE_TIME.as("apply_time"), + EBIKE_USER.MOBILE.as("mobile"), + EBIKE_REFUND.ORDER_ID.as("order_id"), + EBIKE_PAYMENT.TOTAL.as("actual_pay_amount"), + EBIKE_REFUND.REMARK.as("reject_reason"), + EBIKE_REFUND.PROCESS_TIME.as("reject_time"), + EBIKE_PAYMENT.PAYMENT_METHOD.as("payment_method"), + EBIKE_PAYMENT.PAYMENT_TIME.as("payment_time"), + EBIKE_REFUND.REASON.as("apply_reason"), + EBIKE_REFUND.SOURCE.as("source"), + EBIKE_USER.NICKNAME.as("username"), + EBIKE_REFUND.REFUND_METHOD.as("refund_method"), + EBIKE_ORDER_TRANSACTION.BIKE_CODE.as("bike_code"), + EBIKE_ORDER_TRANSACTION.START_TIME.as("start_time"), + EBIKE_ORDER_TRANSACTION.END_TIME.as("end_time"), + EBIKE_ORDER_TRANSACTION.RIDE_POINT, + EBIKE_ORDER_TRANSACTION.RETURN_POINT + ) + .leftJoin(EBIKE_PAYMENT).on(EBIKE_PAYMENT.ORDER_ID.eq(EBIKE_REFUND.ORDER_ID)) + .leftJoin(EBIKE_USER).on(EBIKE_USER.USER_ID.eq(EBIKE_PAYMENT.USER_ID)) + .leftJoin(EBIKE_ORDER_TRANSACTION).on(EBIKE_ORDER_TRANSACTION.ORDER_ID.eq(EBIKE_REFUND.ORDER_ID)) + .where(EBIKE_REFUND.PROCESS_STATUS.eq(String.valueOf(refundDto.getProcessStatus()))); + + // 查询条件 + buildQueryConditions(query, refundDto); + Page page = refundDto.getPageParam().getPage(); + Page list = pageAs(page, query, CloseRefundVo.class); + list.getRecords().forEach(item -> item.setOperationArea(getOperationArea(item.getBikeCode()))); + return list; + } + + @Override + public RefundOrderDetailVo getRefundOrderDetail(Long refundId) { + QueryWrapper query = QueryWrapper.create() + .select(EBIKE_REFUND.REFUND_APPLY.as("apply_refund_amount"), + EBIKE_REFUND.REASON.as("apply_reason"), + EBIKE_REFUND.ORDER_ID.as("order_id"), + EBIKE_PAYMENT.PAYMENT_METHOD.as("payment_method"), + EBIKE_PAYMENT.TOTAL.as("actual_amount"), + EBIKE_PAYMENT.COST_PRICE.as("total_amount"), + EBIKE_USER.NICKNAME.as("username"), + EBIKE_USER.MOBILE.as("mobile") + ) + .leftJoin(EBIKE_PAYMENT).on(EBIKE_PAYMENT.ORDER_ID.eq(EBIKE_REFUND.ORDER_ID)) + .leftJoin(EBIKE_USER).on(EBIKE_USER.USER_ID.eq(EBIKE_PAYMENT.USER_ID)) + .where(EBIKE_REFUND.REFUND_ID.eq(String.valueOf(refundId))); + return getOneAs(query, RefundOrderDetailVo.class); + } + + @Override + public Page queryRefundTradeRecordById(UserQueryDto reqTradeRecordDto) { + QueryWrapper query = QueryWrapper.create() + .from(EBIKE_REFUND) + .select(EBIKE_REFUND.REFUND.as("amount"), EBIKE_REFUND.CREATE_TIME) + .select("'退款' as transaction_content") + .select("'收入' as transaction_type") + .leftJoin(EBIKE_ORDER_TRANSACTION).on(EBIKE_REFUND.ORDER_ID.eq(EBIKE_ORDER_TRANSACTION.ORDER_ID)) + .leftJoin(EBIKE_USER).on(EBIKE_ORDER_TRANSACTION.USER_ID.eq(EBIKE_USER.USER_ID)) + .where(EBIKE_USER.MOBILE.eq(reqTradeRecordDto.getMobile())); + + + QueryWrapper payQuery = QueryWrapper.create() + .from(EBIKE_REFUND) + .select(EBIKE_PAYMENT.TOTAL.as("amount"), + EBIKE_PAYMENT.CREATE_TIME, + EBIKE_ORDER_TRANSACTION.ORDER_TYPE.as("transaction_content")) + .select("'支出' as transaction_type") + .leftJoin(EBIKE_PAYMENT).on(EBIKE_REFUND.ORDER_ID.eq(EBIKE_PAYMENT.ORDER_ID)) + .leftJoin(EBIKE_USER).on(EBIKE_PAYMENT.USER_ID.eq(EBIKE_USER.USER_ID)) + .leftJoin(EBIKE_ORDER_TRANSACTION).on(EBIKE_PAYMENT.ORDER_ID.eq(EBIKE_ORDER_TRANSACTION.ORDER_ID)) + .where(EBIKE_USER.MOBILE.eq(reqTradeRecordDto.getMobile())); + + QueryWrapper all = QueryWrapper.create() + .select("amount", "transaction_content", "transaction_type", "create_time") + .from(query.unionAll(payQuery)).as("a"); + Page page = reqTradeRecordDto.getPageParam().getPage(); + return pageAs(page, all, TransactionRecordVo.class); + } + + @Override + public Page queryRefundRefundRecordById(UserQueryDto reqRefundRecordDto) { + + QueryWrapper query = QueryWrapper.create() + .select(EBIKE_REFUND.REFUND_ID.as("refund_id"), + EBIKE_REFUND.CREATE_TIME.as("apply_time"), + EBIKE_USER.MOBILE.as("mobile"), + EBIKE_REFUND.ORDER_ID, + EBIKE_PAYMENT.TOTAL.as("actual_pay_amount"), + EBIKE_REFUND.REMARK.as("reject_reason"), + EBIKE_REFUND.PROCESS_TIME.as("reject_time"), + EBIKE_PAYMENT.PAYMENT_METHOD.as("payment_method"), + EBIKE_PAYMENT.PAYMENT_TIME.as("payment_time"), + EBIKE_REFUND.REASON.as("apply_reason"), + EBIKE_REFUND.SOURCE.as("source"), + EBIKE_USER.NICKNAME.as("username"), + EBIKE_ORDER_TRANSACTION.BIKE_CODE, + EBIKE_ORDER_TRANSACTION.START_TIME, + EBIKE_ORDER_TRANSACTION.END_TIME, + EBIKE_ORDER_TRANSACTION.RIDE_POINT, + EBIKE_ORDER_TRANSACTION.RETURN_POINT, + EBIKE_REFUND.REFUND.as("refund_amount"), + EBIKE_REFUND.REFUND_TIME.as("arrived_time"), + EBIKE_REFUND.REFUND_STATUS.as("arrived_status"), + EBIKE_REFUND.PROCESS_STATUS.as("handle_status"), + EBIKE_REFUND.REFUND_METHOD.as("refund_method") + ) + .leftJoin(EBIKE_PAYMENT).on(EBIKE_PAYMENT.ORDER_ID.eq(EBIKE_REFUND.ORDER_ID)) + .leftJoin(EBIKE_ORDER_TRANSACTION).on(EBIKE_ORDER_TRANSACTION.ORDER_ID.eq(EBIKE_REFUND.ORDER_ID)) + .leftJoin(EBIKE_USER).on(EBIKE_USER.USER_ID.eq(EBIKE_ORDER_TRANSACTION.USER_ID)) + .where(EBIKE_USER.MOBILE.eq(reqRefundRecordDto.getMobile())); + Page page = reqRefundRecordDto.getPageParam().getPage(); + Page list = pageAs(page, query, RefundRecordListVo.class); + list.getRecords().forEach(item -> item.setOperate(getOperationArea(item.getBikeCode()))); + return list; + } + + @Override + public Page getRefundOrderRecords(UserQueryDto userQueryDto) { + QueryWrapper query = QueryWrapper.create() + .select(EBIKE_ORDER_TRANSACTION.ORDER_ID, + EBIKE_ORDER_TRANSACTION.BIKE_CODE, + EBIKE_ORDER_TRANSACTION.CREATE_TIME, + EBIKE_ORDER_TRANSACTION.START_TIME, + EBIKE_ORDER_TRANSACTION.END_TIME, + EBIKE_ORDER_TRANSACTION.ACTUAL_AMOUNT, + EBIKE_ORDER_TRANSACTION.TOTAL_AMOUNT, + EBIKE_ORDER_TRANSACTION.END_TIME.as("lock_car_time"), + EBIKE_PAYMENT.PAYMENT_TIME.as("payment_time"), + EBIKE_PAYMENT.TRADE_STATUS.as("payment_status"), + EBIKE_PAYMENT.PAYMENT_METHOD.as("pay_method"), + EBIKE_PAYMENT.TRANSACTION_ID.as("trade_serial_number") + ) + .from(EBIKE_ORDER_TRANSACTION).leftJoin(EBIKE_PAYMENT).on(EBIKE_ORDER_TRANSACTION.ORDER_ID.eq(EBIKE_PAYMENT.ORDER_ID)) + .leftJoin(EBIKE_USER).on(EBIKE_USER.USER_ID.eq(EBIKE_ORDER_TRANSACTION.USER_ID)) + .where(EBIKE_USER.MOBILE.eq(userQueryDto.getMobile())); + Page page = userQueryDto.getPageParam().getPage(); + Page list = pageAs(page, query, OrderRecordVo.class); + list.getRecords().forEach(item -> { + item.setOperate(getOperationArea(item.getBikeCode())); + if (item.getStartTime() != null && item.getEndTime() != null) { + item.setCyclingDuration(StringUtils.getDurationTimeString(item.getStartTime(), item.getEndTime())); + } + if (item.getTotalAmount() != null && item.getActualAmount() != null) { + item.setDiscountAmount(item.getTotalAmount().subtract(item.getActualAmount())); + } + item.setHasFaultReport(getFaultReportCount(item.getOrderId()) > 0 ? "是" : "否"); + }); + return list; + } + + /** + * 根据订单id获取故障报告数量 + * + * @param orderId 订单id + * @return 故障报告数量 + */ + private long getFaultReportCount(String orderId) { + QueryWrapper query = QueryWrapper.create() + .select(QueryMethods.count(EBIKE_FAULT_REPORT.ALL_COLUMNS)) + .from(EBIKE_FAULT_REPORT) + .where(EBIKE_FAULT_REPORT.ORDER_CODE.eq(orderId)); + return (long) getObj(query); + } + + + private BigDecimal calculateRefundAmount(Refund refund) { + if (refund == null || refund.getAmount() == null + || refund.getAmount().getRefund() == null) { + log.warn("Refund amount information is incomplete"); + return BigDecimal.ZERO; + } + try { + BigDecimal refundInFen = BigDecimal.valueOf(refund.getAmount().getRefund()); + return refundInFen.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP); + } catch (Exception e) { + log.error("Error calculating refund amount for refund: {}", refund.getOutRefundNo(), e); + return BigDecimal.ZERO; + } + } + + private void buildQueryConditions(QueryWrapper query, RefundQueryDto refundDto) { + // 手机号条件 + if (refundDto.getPhone() != null && !refundDto.getPhone().isEmpty()) { + query.and(EBIKE_USER.MOBILE.like(refundDto.getPhone())); + } + // 订单号条件 + if (refundDto.getOrderId() != null && !refundDto.getOrderId().isEmpty()) { + query.and(EBIKE_REFUND.ORDER_ID.like(refundDto.getOrderId())); + } + // 退款时间范围条件 + if (refundDto.getRefundTime() != null && !refundDto.getRefundTime().isEmpty()) { + query.and(EBIKE_REFUND.REFUND_TIME.ge(refundDto.getRefundTime().get(GlobalConstants.NUMBER_ZERO))); + + if (refundDto.getRefundTime().size() == GlobalConstants.NUMBER_TWO) { + query.and(EBIKE_REFUND.REFUND_TIME.le(refundDto.getRefundTime().get(GlobalConstants.NUMBER_ONE))); + } + } + } + +}