“mitao”
2026-04-15 5ad8d714d43ecf06aa9d900a69e7b22018ce7ed6
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/live/service/CoursePurchaseOrderAppService.java
@@ -4,6 +4,9 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tcm.training.admin.app.auth.service.AppAuthSessionService;
import com.tcm.training.admin.app.course.vo.AppCoursePurchaseOrderDetailVO;
import com.tcm.training.admin.app.course.vo.AppCoursePurchaseOrderItemVO;
import com.tcm.training.admin.common.DateTimes;
import com.tcm.training.admin.common.PageResponse;
import com.tcm.training.admin.common.PhoneMasker;
@@ -36,11 +39,20 @@
    private static final String PAYMENT_METHOD_ALIPAY = "ALIPAY";
    private final CoursePurchaseOrderMapper coursePurchaseOrderMapper;
    private final AppAuthSessionService appAuthSessionService;
    public CoursePurchaseOrderAppService(CoursePurchaseOrderMapper coursePurchaseOrderMapper) {
    /**
     * 注入养生课程购买订单服务依赖。
     */
    public CoursePurchaseOrderAppService(CoursePurchaseOrderMapper coursePurchaseOrderMapper,
                                         AppAuthSessionService appAuthSessionService) {
        this.coursePurchaseOrderMapper = coursePurchaseOrderMapper;
        this.appAuthSessionService = appAuthSessionService;
    }
    /**
     * 分页查询后台养生课程购买订单。
     */
    public PageResponse<CoursePurchaseOrderListItemVO> page(int page,
                                                            int pageSize,
                                                            String orderNo,
@@ -63,6 +75,34 @@
        return PageResponse.of(toList(result.getRecords()), result.getTotal(), result.getCurrent(), result.getSize());
    }
    /**
     * 分页查询当前登录用户的 APP 购课记录。
     */
    public PageResponse<AppCoursePurchaseOrderItemVO> appUserPage(int page, int pageSize, String productName) {
        Long userId = appAuthSessionService.requireLoginUserId();
        IPage<CoursePurchaseOrderListRow> result = coursePurchaseOrderMapper.selectAppUserOrderPage(
                new Page<CoursePurchaseOrderListRow>(page, pageSize),
                userId,
                trimToNull(productName)
        );
        return PageResponse.of(toAppList(result.getRecords()), result.getTotal(), result.getCurrent(), result.getSize());
    }
    /**
     * 获取当前登录用户的 APP 购课记录详情。
     */
    public AppCoursePurchaseOrderDetailVO appUserDetail(String orderNo) {
        Long userId = appAuthSessionService.requireLoginUserId();
        CoursePurchaseOrderListRow row = coursePurchaseOrderMapper.selectAppUserOrderDetail(userId, trimToNull(orderNo));
        if (row == null) {
            throw new IllegalArgumentException("购课记录不存在");
        }
        return toAppDetail(row);
    }
    /**
     * 导出后台养生课程购买订单。
     */
    public void export(HttpServletResponse response,
                       String orderNo,
                       String userPhone,
@@ -117,6 +157,9 @@
        throw new IllegalArgumentException("退款功能待支付方案确认后接入");
    }
    /**
     * 删除后台已退款养生课程购买订单。
     */
    @Transactional
    public void delete(Long id) {
        CoursePurchaseOrder order = requireOrder(id);
@@ -126,6 +169,9 @@
        coursePurchaseOrderMapper.deleteById(id);
    }
    /**
     * 校验养生课程购买订单存在。
     */
    private CoursePurchaseOrder requireOrder(Long id) {
        CoursePurchaseOrder order = coursePurchaseOrderMapper.selectOne(new LambdaQueryWrapper<CoursePurchaseOrder>()
                .eq(CoursePurchaseOrder::getId, id)
@@ -138,6 +184,9 @@
        return order;
    }
    /**
     * 将后台订单查询结果转换为后台列表响应。
     */
    private List<CoursePurchaseOrderListItemVO> toList(List<CoursePurchaseOrderListRow> rows) {
        List<CoursePurchaseOrderListItemVO> list = new ArrayList<CoursePurchaseOrderListItemVO>();
        for (CoursePurchaseOrderListRow row : rows) {
@@ -158,6 +207,62 @@
        return list;
    }
    /**
     * 将订单查询结果转换为 APP 购课记录列表响应。
     */
    private List<AppCoursePurchaseOrderItemVO> toAppList(List<CoursePurchaseOrderListRow> rows) {
        List<AppCoursePurchaseOrderItemVO> list = new ArrayList<AppCoursePurchaseOrderItemVO>();
        for (CoursePurchaseOrderListRow row : rows) {
            AppCoursePurchaseOrderItemVO item = new AppCoursePurchaseOrderItemVO();
            item.setId(row.getId());
            item.setOrderNo(row.getOrderNo());
            item.setCourseId(row.getCourseId());
            item.setCourseVideoId(row.getCourseVideoId());
            item.setProductName(row.getProductName());
            item.setCourseTitle(row.getCourseTitle());
            item.setChapterName(row.getChapterName());
            item.setCoverImage(row.getCoverImage());
            item.setOrderAmount(row.getOrderAmount());
            item.setPaymentMethod(row.getPaymentMethod());
            item.setPaymentMethodText(paymentMethodText(row.getPaymentMethod()));
            item.setStatus(row.getStatus());
            // APP 购课记录页只需标记是否退款,避免前端重复判断订单状态。
            item.setShowRefundTag(Boolean.valueOf(STATUS_REFUNDED.equals(row.getStatus())));
            item.setPaidAt(row.getPaidAt());
            list.add(item);
        }
        return list;
    }
    /**
     * 将订单详情查询结果转换为 APP 购课记录详情响应。
     */
    private AppCoursePurchaseOrderDetailVO toAppDetail(CoursePurchaseOrderListRow row) {
        AppCoursePurchaseOrderDetailVO detail = new AppCoursePurchaseOrderDetailVO();
        detail.setId(row.getId());
        detail.setOrderNo(row.getOrderNo());
        detail.setCourseId(row.getCourseId());
        detail.setCourseVideoId(row.getCourseVideoId());
        detail.setProductName(row.getProductName());
        detail.setCourseTitle(row.getCourseTitle());
        detail.setChapterName(row.getChapterName());
        detail.setCoverImage(row.getCoverImage());
        detail.setOrderAmount(row.getOrderAmount());
        detail.setPaymentMethod(row.getPaymentMethod());
        detail.setPaymentMethodText(paymentMethodText(row.getPaymentMethod()));
        detail.setStatus(row.getStatus());
        // 详情页退款信息直接由后端归一化,避免前端重复拼装退款状态。
        detail.setRefundAmount(resolveRefundAmount(row.getStatus(), row.getOrderAmount(), row.getRefundAmount()));
        detail.setShowRefundTag(Boolean.valueOf(STATUS_REFUNDED.equals(row.getStatus())));
        detail.setCreatedAt(row.getCreatedAt());
        detail.setPaidAt(row.getPaidAt());
        detail.setRefundedAt(row.getRefundedAt());
        return detail;
    }
    /**
     * 解析订单应展示的退款金额。
     */
    private BigDecimal resolveRefundAmount(String status, BigDecimal orderAmount, BigDecimal refundAmount) {
        if (!STATUS_REFUNDED.equals(status)) {
            return null;
@@ -165,6 +270,9 @@
        return refundAmount == null ? orderAmount : refundAmount;
    }
    /**
     * 归一化后台筛选状态。
     */
    private String normalizeStatus(String status) {
        String normalized = trimToNull(status);
        if (normalized == null) {
@@ -176,6 +284,9 @@
        return null;
    }
    /**
     * 将空白字符串归一化为 null。
     */
    private String trimToNull(String value) {
        if (value == null) {
            return null;
@@ -184,10 +295,16 @@
        return trimmed.isEmpty() ? null : trimmed;
    }
    /**
     * 缺省文本兜底。
     */
    private String defaultText(String value) {
        return value == null || value.trim().isEmpty() ? "-" : value.trim();
    }
    /**
     * 解析支付方式展示文案。
     */
    private String paymentMethodText(String paymentMethod) {
        if (PAYMENT_METHOD_WECHAT.equals(paymentMethod)) {
            return "微信支付";
@@ -198,6 +315,9 @@
        return "-";
    }
    /**
     * 解析订单状态展示文案。
     */
    private String statusText(String status) {
        if (STATUS_WAITING_PAYMENT.equals(status)) {
            return "待支付";