Forráskód Böngészése

Merge branch 'main' of http://47.98.207.247:3000/lsq/ship-ota-server

lishiqiang 2 hete
szülő
commit
1d997c0f6f

+ 42 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/report/BankStatementReportController.java

@@ -5,7 +5,10 @@ import com.yc.ship.framework.common.pojo.CommonResult;
 import com.yc.ship.framework.common.pojo.PageResult;
 import com.yc.ship.module.trade.controller.admin.report.vo.BankStatementReportPageReqVO;
 import com.yc.ship.module.trade.controller.admin.report.vo.BankStatementReportRespVO;
+import com.yc.ship.module.trade.controller.admin.report.vo.IncomeOrderLedgerPageReqVO;
+import com.yc.ship.module.trade.controller.admin.report.vo.IncomeOrderLedgerRespVO;
 import com.yc.ship.module.trade.service.report.BankStatementReportService;
+import com.yc.ship.module.trade.service.report.IncomeOrderLedgerService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
@@ -38,6 +41,9 @@ public class BankStatementReportController {
     @Resource
     private BankStatementReportService bankStatementReportService;
 
+    @Resource
+    private IncomeOrderLedgerService incomeOrderLedgerService;
+
     /**
      * 查询银行对账报表分页
      *
@@ -68,4 +74,40 @@ public class BankStatementReportController {
         bankStatementReportService.exportBankStatementReportExcel(pageReqVO, response);
     }
 
+    // ==================== 订单收入台账接口 ====================
+
+    /**
+     * 查询订单收入台账分页
+     *
+     * @param pageReqVO 分页查询条件
+     * @return 分页结果
+     */
+    @GetMapping("/income-order-ledger/page")
+    @Operation(summary = "查询订单收入台账分页")
+/*
+    @PreAuthorize("@ss.hasPermission('trade:report:bank-statement:query')")
+*/
+    public CommonResult<PageResult<IncomeOrderLedgerRespVO>> getIncomeOrderLedgerPage(@Valid IncomeOrderLedgerPageReqVO pageReqVO) {
+        PageResult<IncomeOrderLedgerRespVO> pageResult = incomeOrderLedgerService.getIncomeOrderLedgerPage(pageReqVO);
+        return success(pageResult);
+    }
+
+    /**
+     * 导出订单收入台账 Excel(数字字段导出为数字格式)
+     *
+     * @param pageReqVO 查询条件
+     * @param response  HTTP响应
+     * @throws IOException IO异常
+     */
+    @GetMapping("/income-order-ledger/export-excel")
+    @Operation(summary = "导出订单收入台账 Excel")
+/*
+    @PreAuthorize("@ss.hasPermission('trade:report:bank-statement:export')")
+*/
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportIncomeOrderLedgerExcel(@Valid IncomeOrderLedgerPageReqVO pageReqVO,
+                                              HttpServletResponse response) throws IOException {
+        incomeOrderLedgerService.exportIncomeOrderLedgerExcel(pageReqVO, response);
+    }
+
 }

+ 50 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/report/vo/IncomeOrderLedgerPageReqVO.java

@@ -0,0 +1,50 @@
+package com.yc.ship.module.trade.controller.admin.report.vo;
+
+import com.yc.ship.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+
+import static com.yc.ship.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
+
+/**
+ * 订单收入台账分页查询 Request VO
+ *
+ * @author 管理员
+ */
+@Schema(description = "管理后台 - 订单收入台账分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class IncomeOrderLedgerPageReqVO extends PageParam {
+
+    @Schema(description = "订单编号", example = "CJXLY-20260204-YC-1")
+    private String orderNo;
+
+    @Schema(description = "订单状态", example = "1")
+    private Integer orderStatus;
+
+    @Schema(description = "支付状态", example = "1")
+    private Integer paymentStatus;
+
+    @Schema(description = "开航时间", example = "2024-03-01")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
+    private LocalDate sailTime;
+
+    @Schema(description = "组团社", example = "长江国际旅行社")
+    private String travelAgency;
+
+    @Schema(description = "游轮ID", example = "1")
+    private Long shipId;
+
+    @Schema(description = "航线名称", example = "重庆-宜昌三峡游")
+    private String routeName;
+
+    @Schema(description = "房型名称", example = "标准间")
+    private String roomTypeName;
+
+}

+ 108 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/report/vo/IncomeOrderLedgerRespVO.java

@@ -0,0 +1,108 @@
+package com.yc.ship.module.trade.controller.admin.report.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.format.NumberFormat;
+import com.yc.ship.framework.excel.core.annotations.DictFormat;
+import com.yc.ship.framework.excel.core.convert.DictConvert;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 订单收入台账 Response VO(同时用于 Excel 导出)
+ *
+ * @author 管理员
+ */
+@Schema(description = "管理后台 - 订单收入台账 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class IncomeOrderLedgerRespVO {
+
+    @Schema(description = "主键ID", hidden = true)
+    private Long id;
+
+    @Schema(description = "订单编号", example = "CJXLY-20260204-YC-1")
+    @ExcelProperty("订单编号")
+    private String orderNo;
+
+    @Schema(description = "订单状态", example = "1")
+    @ExcelProperty(value = "订单状态", converter = DictConvert.class)
+    @DictFormat("trade_order_status")
+    private Integer orderStatus;
+
+    @Schema(description = "支付状态", example = "1")
+    @ExcelProperty(value = "支付状态", converter = DictConvert.class)
+    @DictFormat("payment_status")
+    private Integer paymentStatus;
+
+    @Schema(description = "开航时间", example = "2024/03/01")
+    @ExcelProperty("开航时间")
+    private String sailTime;
+
+    @Schema(description = "组团社", example = "长江国际旅行社")
+    @ExcelProperty("组团社")
+    private String travelAgency;
+
+    @Schema(description = "航次", example = "长江行 揽月2026-05-05")
+    @ExcelProperty("航次")
+    private String voyage;
+
+    @Schema(description = "航线名称", example = "重庆-宜昌三峡游")
+    @ExcelProperty("航线名称")
+    private String routeName;
+
+    @Schema(description = "房型名称", example = "标准间")
+    @ExcelProperty("房型名称")
+    private String roomTypeName;
+
+    @Schema(description = "房间总数", example = "5")
+    @ExcelProperty("房间总数")
+    private Integer roomCount;
+
+    @Schema(description = "成人数", example = "10")
+    @ExcelProperty("成人数")
+    private Integer adultCount;
+
+    @Schema(description = "儿童数", example = "3")
+    @ExcelProperty("儿童数")
+    private Integer childCount;
+
+    @Schema(description = "婴儿数", example = "1")
+    @ExcelProperty("婴儿数")
+    private Integer infantCount;
+
+    @Schema(description = "陪同数", example = "2")
+    @ExcelProperty("陪同数")
+    private Integer companionCount;
+
+    @Schema(description = "免票数", example = "1")
+    @ExcelProperty("免票")
+    private Integer freeCount;
+
+    @Schema(description = "总人数", example = "17")
+    @ExcelProperty("总人数")
+    private Integer totalCount;
+
+    @Schema(description = "营销价格", example = "5000.00")
+    @NumberFormat("0.00")
+    @ExcelProperty("营销价格")
+    private BigDecimal marketingPrice;
+
+    @Schema(description = "优惠金额", example = "200.00")
+    @NumberFormat("0.00")
+    @ExcelProperty("优惠金额")
+    private BigDecimal discountAmount;
+
+    @Schema(description = "退票手续费", example = "50.00")
+    @NumberFormat("0.00")
+    @ExcelProperty("退票手续费")
+    private BigDecimal refundFee;
+
+    @Schema(description = "实际结算价格", example = "4750.00")
+    @NumberFormat("0.00")
+    @ExcelProperty("实际结算价格")
+    private BigDecimal actualSettlementPrice;
+
+}

+ 38 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/dal/mysql/report/IncomeOrderLedgerMapper.java

@@ -0,0 +1,38 @@
+package com.yc.ship.module.trade.dal.mysql.report;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yc.ship.framework.mybatis.core.mapper.BaseMapperX;
+import com.yc.ship.module.trade.controller.admin.report.vo.IncomeOrderLedgerPageReqVO;
+import com.yc.ship.module.trade.controller.admin.report.vo.IncomeOrderLedgerRespVO;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 订单收入台账 Mapper
+ *
+ * @author 管理员
+ */
+@Mapper
+public interface IncomeOrderLedgerMapper extends BaseMapperX<IncomeOrderLedgerRespVO> {
+
+    /**
+     * 分页查询订单收入台账
+     *
+     * @param page   分页参数
+     * @param vo 查询条件
+     * @return 分页结果
+     */
+    IPage<IncomeOrderLedgerRespVO> selectIncomeOrderLedgerPage(
+            IPage<IncomeOrderLedgerRespVO> page, @Param("vo") IncomeOrderLedgerPageReqVO vo);
+
+    /**
+     * 导出查询订单收入台账(不分页,用于 Excel 导出)
+     *
+     * @param vo 查询条件
+     * @return 数据列表
+     */
+    List<IncomeOrderLedgerRespVO> selectIncomeOrderLedgerExportList(@Param("vo") IncomeOrderLedgerPageReqVO vo);
+
+}

+ 34 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/report/IncomeOrderLedgerService.java

@@ -0,0 +1,34 @@
+package com.yc.ship.module.trade.service.report;
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.module.trade.controller.admin.report.vo.IncomeOrderLedgerPageReqVO;
+import com.yc.ship.module.trade.controller.admin.report.vo.IncomeOrderLedgerRespVO;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 订单收入台账 Service 接口
+ *
+ * @author 管理员
+ */
+public interface IncomeOrderLedgerService {
+
+    /**
+     * 查询订单收入台账分页
+     *
+     * @param pageReqVO 分页查询条件
+     * @return 分页结果
+     */
+    PageResult<IncomeOrderLedgerRespVO> getIncomeOrderLedgerPage(IncomeOrderLedgerPageReqVO pageReqVO);
+
+    /**
+     * 导出订单收入台账 Excel
+     *
+     * @param pageReqVO 查询条件
+     * @param response  HTTP响应
+     * @throws IOException IO异常
+     */
+    void exportIncomeOrderLedgerExcel(IncomeOrderLedgerPageReqVO pageReqVO, HttpServletResponse response) throws IOException;
+
+}

+ 125 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/report/impl/IncomeOrderLedgerServiceImpl.java

@@ -0,0 +1,125 @@
+package com.yc.ship.module.trade.service.report.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.excel.core.util.ExcelUtils;
+import com.yc.ship.module.trade.controller.admin.report.vo.IncomeOrderLedgerPageReqVO;
+import com.yc.ship.module.trade.controller.admin.report.vo.IncomeOrderLedgerRespVO;
+import com.yc.ship.module.trade.dal.mysql.report.IncomeOrderLedgerMapper;
+import com.yc.ship.module.trade.service.report.IncomeOrderLedgerService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 订单收入台账 Service 实现类
+ *
+ * @author 管理员
+ */
+@Service
+@Slf4j
+public class IncomeOrderLedgerServiceImpl implements IncomeOrderLedgerService {
+
+    @Resource
+    private IncomeOrderLedgerMapper incomeOrderLedgerMapper;
+
+    /**
+     * 查询订单收入台账分页
+     *
+     * @param pageReqVO 分页查询条件
+     * @return 分页结果
+     */
+    @Override
+    public PageResult<IncomeOrderLedgerRespVO> getIncomeOrderLedgerPage(IncomeOrderLedgerPageReqVO pageReqVO) {
+        IPage<IncomeOrderLedgerRespVO> page = incomeOrderLedgerMapper.selectIncomeOrderLedgerPage(
+                new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO);
+        return new PageResult<>(page.getRecords(), page.getTotal());
+    }
+
+    /**
+     * 导出订单收入台账 Excel
+     *
+     * @param pageReqVO 查询条件
+     * @param response  HTTP响应
+     * @throws IOException IO异常
+     */
+    @Override
+    public void exportIncomeOrderLedgerExcel(IncomeOrderLedgerPageReqVO pageReqVO,
+                                             HttpServletResponse response) throws IOException {
+        // 1. 查询所有数据(不分页)
+        List<IncomeOrderLedgerRespVO> list = incomeOrderLedgerMapper.selectIncomeOrderLedgerExportList(pageReqVO);
+        if (CollUtil.isEmpty(list)) {
+            log.warn("[exportIncomeOrderLedgerExcel] 无数据可导出");
+        } else {
+            // 2. 计算合计行并追加到列表末尾
+            IncomeOrderLedgerRespVO summary = calculateSummary(list);
+            list.add(summary);
+        }
+        // 3. 导出 Excel(数字字段使用 @NumberFormat 注解确保导出为数字格式)
+        ExcelUtils.write(response, "订单收入台账.xls", "订单收入台账", IncomeOrderLedgerRespVO.class, list);
+    }
+
+    /**
+     * 计算合计行数据
+     */
+    private IncomeOrderLedgerRespVO calculateSummary(List<IncomeOrderLedgerRespVO> list) {
+        IncomeOrderLedgerRespVO summary = new IncomeOrderLedgerRespVO();
+        summary.setOrderNo("合计");
+        summary.setSailTime(null);
+        summary.setTravelAgency(null);
+        summary.setVoyage(null);
+        summary.setRouteName(null);
+        summary.setRoomTypeName(null);
+
+        BigDecimal totalMarketingPrice = BigDecimal.ZERO;
+        BigDecimal totalDiscountAmount = BigDecimal.ZERO;
+        BigDecimal totalRefundFee = BigDecimal.ZERO;
+        BigDecimal totalActualSettlementPrice = BigDecimal.ZERO;
+        int totalRoomCount = 0;
+        int totalAdultCount = 0;
+        int totalChildCount = 0;
+        int totalInfantCount = 0;
+        int totalCompanionCount = 0;
+        int totalFreeCount = 0;
+        int totalCountSum = 0;
+
+        for (IncomeOrderLedgerRespVO item : list) {
+            totalRoomCount += item.getRoomCount() != null ? item.getRoomCount() : 0;
+            totalAdultCount += item.getAdultCount() != null ? item.getAdultCount() : 0;
+            totalChildCount += item.getChildCount() != null ? item.getChildCount() : 0;
+            totalInfantCount += item.getInfantCount() != null ? item.getInfantCount() : 0;
+            totalCompanionCount += item.getCompanionCount() != null ? item.getCompanionCount() : 0;
+            totalFreeCount += item.getFreeCount() != null ? item.getFreeCount() : 0;
+            totalCountSum += item.getTotalCount() != null ? item.getTotalCount() : 0;
+            totalMarketingPrice = totalMarketingPrice.add(
+                    item.getMarketingPrice() != null ? item.getMarketingPrice() : BigDecimal.ZERO);
+            totalDiscountAmount = totalDiscountAmount.add(
+                    item.getDiscountAmount() != null ? item.getDiscountAmount() : BigDecimal.ZERO);
+            totalRefundFee = totalRefundFee.add(
+                    item.getRefundFee() != null ? item.getRefundFee() : BigDecimal.ZERO);
+            totalActualSettlementPrice = totalActualSettlementPrice.add(
+                    item.getActualSettlementPrice() != null ? item.getActualSettlementPrice() : BigDecimal.ZERO);
+        }
+
+        summary.setRoomCount(totalRoomCount);
+        summary.setAdultCount(totalAdultCount);
+        summary.setChildCount(totalChildCount);
+        summary.setInfantCount(totalInfantCount);
+        summary.setCompanionCount(totalCompanionCount);
+        summary.setFreeCount(totalFreeCount);
+        summary.setTotalCount(totalCountSum);
+        summary.setMarketingPrice(totalMarketingPrice);
+        summary.setDiscountAmount(totalDiscountAmount);
+        summary.setRefundFee(totalRefundFee);
+        summary.setActualSettlementPrice(totalActualSettlementPrice);
+        return summary;
+    }
+
+}

+ 77 - 4
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/utils/excel/ExcelStyleHandler.java

@@ -8,9 +8,9 @@ import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.RegionUtil;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 public class ExcelStyleHandler implements CellWriteHandler {
     private int templateRowIndex;
@@ -218,7 +218,79 @@ public class ExcelStyleHandler implements CellWriteHandler {
         }
     }
 
+
+    /**
+     * 优化后:预计算合并区间,批量添加
+     * 时间复杂度:O(n × k),相比原来的 O(n² × k × m) 有数量级提升
+     */
+    private void performMerge(Sheet sheet) {
+        if (visitorList == null || visitorList.size() <= 1) return;
+
+        int n = visitorList.size();
+
+        // 按列收集需要合并的区间:列索引 -> List<起始行(相对), 结束行(相对)>
+        Map<Integer, List<int[]>> mergeRanges = new HashMap<>();
+
+        // 预定义每种类型需要合并的列
+        List<Integer> sourceCols = Collections.singletonList(0);           // 代理商:第0列
+        List<Integer> orderCols = Arrays.asList(1, 2, 3, 4, 5, 6,       // 订单信息:第1-7列
+                        fileType == 1 ? 7 : -1, fileType == 1 ? 8 : -1).stream()
+                .filter(c -> c >= 0).collect(Collectors.toList());
+        List<Integer> roomCols = (fileType == 1
+                ? Arrays.asList( 9, 10, 11)                                // 房间信息(fileType=1):第8-10列
+                : Arrays.asList(7, 8, 9));                               // 房间信息(fileType≠1):第7-9列
+
+        for (int col : sourceCols) collectMergeRanges(mergeRanges, col, n,
+                i -> safeString(visitorList.get(i).getSourceName()));
+        for (int col : orderCols) collectMergeRanges(mergeRanges, col, n,
+                i -> safeString(visitorList.get(i).getOrderNo()));
+        for (int col : roomCols) collectMergeRanges(mergeRanges, col, n,
+                i -> safeString(visitorList.get(i).getRoomIndexId()) + "_" + safeString(visitorList.get(i).getOrderNo()));
+
+        // 批量添加所有合并区域
+        for (Map.Entry<Integer, List<int[]>> entry : mergeRanges.entrySet()) {
+            int col = entry.getKey();
+            for (int[] range : entry.getValue()) {
+                sheet.addMergedRegion(new CellRangeAddress(
+                        DATA_START_ROW + range[0], DATA_START_ROW + range[1], col, col));
+            }
+        }
+    }
+
+    /** 收集某一列的所有连续相同值区间 */
+    private void collectMergeRanges(Map<Integer, List<int[]>> mergeRanges, int col, int n,
+                                    Function<Integer, String> valueGetter) {
+        List<int[]> ranges = new ArrayList<>();
+        int start = 0;
+        String prevValue = valueGetter.apply(0);
+
+        for (int i = 1; i < n; i++) {
+            String currValue = valueGetter.apply(i);
+            if (!currValue.equals(prevValue)) {
+                if (start < i - 1) { // 连续多行相同才需要合并
+                    ranges.add(new int[]{start, i - 1});
+                }
+                start = i;
+                prevValue = currValue;
+            }
+        }
+        // 处理最后一组
+        if (start < n - 1) {
+            ranges.add(new int[]{start, n - 1});
+        }
+
+        if (!ranges.isEmpty()) {
+            mergeRanges.put(col, ranges);
+        }
+    }
+
+    private String safeString(String s) {
+        return s != null ? s : "";
+    }
+
+
     /**
+     * 废弃
      * 执行合并操作
      * 此方法在数据写入完成后统一处理合并,避免逐行合并时的磁盘刷新问题
      *
@@ -229,8 +301,9 @@ public class ExcelStyleHandler implements CellWriteHandler {
      * 4. 横向不需要合并(按列单独合并)
      *
      * @param sheet Excel工作表
+     * TODO 性能低下
      */
-    private void performMerge(Sheet sheet) {
+    private void performMerge1(Sheet sheet) {
         // 遍历游客列表,从第二行开始与上一行比较
         for (int i = 1; i < visitorList.size(); i++) {
             TouristExportVisitorVO currentVisitor = visitorList.get(i);

+ 8 - 3
ship-module-trade/ship-module-trade-biz/src/main/resources/mapper/order/TradeVisitorMapper.xml

@@ -206,10 +206,14 @@
     <select id="selectListByVoyageId" resultType="com.yc.ship.module.trade.dal.dataobject.order.TradeVisitorDO">
         select tv.*,if(pprmt.total_num &gt;=2 and pprmt.enable_share=0,1,0) as isHaveTogethers,if(pprmt.total_num =1 and pprmt.enable_share=0,1,0) as isAlone
         from trade_visitor tv
-        join trade_order to1 on tv.order_id=to1.id
-        join trade_order_room_model torm on tv.room_index_id=torm.room_index_id
-        join product_price_room_model_type pprmt on torm.room_model_type_id = pprmt.id
+                 join trade_order to1 on tv.order_id=to1.id
+                 join trade_order_room_model torm on tv.room_index_id=torm.room_index_id
+                 join product_price_room_model_type pprmt on torm.room_model_type_id = pprmt.id
         where to1.voyage_id=#{voyageId} and to1.order_status=6
+            join trade_order to1 on tv.order_id=to1.id and to1.deleted=0
+            join trade_order_room_model torm on tv.room_index_id=torm.room_index_id and torm.deleted=0
+            join product_price_room_model_type pprmt on torm.room_model_type_id = pprmt.id and pprmt.deleted=0
+        where to1.voyage_id=#{voyageId} and to1.order_status=6 and tv.deleted=0
     </select>
 
     <select id="selectListByVoyageIdAndRoomId"
@@ -217,6 +221,7 @@
         select tv.*
         from trade_visitor tv
                  join trade_order b on tv.order_id=b.id
+                 join trade_order b on tv.order_id=b.id and b.deleted=0
         where b.order_status=6 and b.voyage_id=#{voyageId} and if(tv.final_room_id is null,tv.init_room_id,tv.final_room_id)=#{roomId}
     </select>
 

+ 153 - 0
ship-module-trade/ship-module-trade-biz/src/main/resources/mapper/report/IncomeOrderLedgerMapper.xml

@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.yc.ship.module.trade.dal.mysql.report.IncomeOrderLedgerMapper">
+
+    <!-- 分页查询订单收入台账 -->
+    <select id="selectIncomeOrderLedgerPage"
+            resultType="com.yc.ship.module.trade.controller.admin.report.vo.IncomeOrderLedgerRespVO">
+        SELECT
+            o.id,
+            o.order_no AS orderNo,
+            o.order_status AS orderStatus,
+            o.pay_status AS paymentStatus,
+            DATE_FORMAT(v.start_time, '%Y/%m/%d') AS sailTime,
+            o.source_name AS travelAgency,
+            v.name AS voyage,
+            r.name AS routeName,
+            rm.room_model_name AS roomTypeName,
+            IFNULL(tot.use_room_total_num, 0) AS roomCount,
+            IFNULL(tot.adult_total_num, 0) AS adultCount,
+            IFNULL(tot.child_total_num, 0) AS childCount,
+            IFNULL(tot.baby_total_num, 0) AS infantCount,
+            IFNULL(tot.with_total_num, 0) AS companionCount,
+            IFNULL(tot.free_num, 0) AS freeCount,
+            (IFNULL(tot.adult_total_num, 0) + IFNULL(tot.child_total_num, 0) +
+             IFNULL(tot.baby_total_num, 0) + IFNULL(tot.with_total_num, 0) + IFNULL(tot.free_num, 0)) AS totalCount,
+            o.amount AS marketingPrice,
+            o.free_amount AS discountAmount,
+            COALESCE(refund_fee_sum.refundFee, 0) AS refundFee,
+            (o.amount - IFNULL(o.free_amount, 0) - COALESCE(refund_fee_sum.refundFee, 0)) AS actualSettlementPrice
+        FROM trade_order o
+        INNER JOIN product_voyage v ON o.voyage_id = v.id AND v.deleted = 0
+        INNER JOIN resource_route r ON v.route_id = r.id AND r.deleted = 0
+        LEFT JOIN trade_order_total tot ON o.id = tot.old_order_id AND tot.deleted = 0
+        LEFT JOIN (
+            SELECT rm.order_id,
+                   GROUP_CONCAT(DISTINCT rm.room_model_name SEPARATOR ',') AS room_model_name
+            FROM trade_order_room_model rm
+            WHERE rm.deleted = 0
+            GROUP BY rm.order_id
+        ) rm ON o.id = rm.order_id
+        LEFT JOIN (
+            SELECT order_id, SUM(fee) AS refundFee
+            FROM trade_refund
+            WHERE deleted = 0 AND refund_status IN (3)
+            GROUP BY order_id
+        ) refund_fee_sum ON o.id = refund_fee_sum.order_id
+        WHERE o.deleted = 0
+        <if test="vo.orderNo != null and vo.orderNo != ''">
+            AND o.order_no LIKE CONCAT('%', #{vo.orderNo}, '%')
+        </if>
+        <if test="vo.orderStatus != null">
+            AND o.order_status = #{vo.orderStatus}
+        </if>
+        <if test="vo.paymentStatus != null">
+            AND o.pay_status = #{vo.paymentStatus}
+        </if>
+        <if test="vo.sailTime != null">
+            AND DATE(v.start_time) = #{vo.sailTime}
+        </if>
+        <if test="vo.travelAgency != null and vo.travelAgency != ''">
+            AND o.source_name LIKE CONCAT('%', #{vo.travelAgency}, '%')
+        </if>
+        <if test="vo.shipId != null">
+            AND v.ship_id = #{vo.shipId}
+        </if>
+        <if test="vo.routeName != null and vo.routeName != ''">
+            AND r.name LIKE CONCAT('%', #{vo.routeName}, '%')
+        </if>
+        <if test="vo.roomTypeName != null and vo.roomTypeName != ''">
+            AND EXISTS (
+                SELECT 1 FROM trade_order_room_model orm2
+                WHERE orm2.order_id = o.id AND orm2.deleted = 0
+                AND orm2.room_model_name LIKE CONCAT('%', #{vo.roomTypeName}, '%')
+            )
+        </if>
+        ORDER BY o.create_time DESC
+    </select>
+
+    <!-- 导出查询(与分页查询条件一致,不分页) -->
+    <select id="selectIncomeOrderLedgerExportList"
+            resultType="com.yc.ship.module.trade.controller.admin.report.vo.IncomeOrderLedgerRespVO">
+        SELECT
+            o.id,
+            o.order_no AS orderNo,
+            o.order_status AS orderStatus,
+            o.pay_status AS paymentStatus,
+            DATE_FORMAT(v.start_time, '%Y/%m/%d') AS sailTime,
+            o.source_name AS travelAgency,
+            v.name AS voyage,
+            r.name AS routeName,
+            rm.room_model_name AS roomTypeName,
+            IFNULL(tot.use_room_total_num, 0) AS roomCount,
+            IFNULL(tot.adult_total_num, 0) AS adultCount,
+            IFNULL(tot.child_total_num, 0) AS childCount,
+            IFNULL(tot.baby_total_num, 0) AS infantCount,
+            IFNULL(tot.with_total_num, 0) AS companionCount,
+            IFNULL(tot.free_num, 0) AS freeCount,
+            (IFNULL(tot.adult_total_num, 0) + IFNULL(tot.child_total_num, 0) +
+             IFNULL(tot.baby_total_num, 0) + IFNULL(tot.with_total_num, 0) + IFNULL(tot.free_num, 0)) AS totalCount,
+            o.amount AS marketingPrice,
+            o.free_amount AS discountAmount,
+            COALESCE(refund_fee_sum.refundFee, 0) AS refundFee,
+            (o.amount - IFNULL(o.free_amount, 0) - COALESCE(refund_fee_sum.refundFee, 0)) AS actualSettlementPrice
+        FROM trade_order o
+        INNER JOIN product_voyage v ON o.voyage_id = v.id AND v.deleted = 0
+        INNER JOIN resource_route r ON v.route_id = r.id AND r.deleted = 0
+        LEFT JOIN trade_order_total tot ON o.id = tot.old_order_id AND tot.deleted = 0
+        LEFT JOIN (
+            SELECT rm.order_id,
+                   GROUP_CONCAT(DISTINCT rm.room_model_name SEPARATOR ',') AS room_model_name
+            FROM trade_order_room_model rm
+            WHERE rm.deleted = 0
+            GROUP BY rm.order_id
+        ) rm ON o.id = rm.order_id
+        LEFT JOIN (
+            SELECT order_id, SUM(fee) AS refundFee
+            FROM trade_refund
+            WHERE deleted = 0 AND refund_status IN (3)
+            GROUP BY order_id
+        ) refund_fee_sum ON o.id = refund_fee_sum.order_id
+        WHERE o.deleted = 0
+        <if test="vo.orderNo != null and vo.orderNo != ''">
+            AND o.order_no LIKE CONCAT('%', #{vo.orderNo}, '%')
+        </if>
+        <if test="vo.orderStatus != null">
+            AND o.order_status = #{vo.orderStatus}
+        </if>
+        <if test="vo.paymentStatus != null">
+            AND o.pay_status = #{vo.paymentStatus}
+        </if>
+        <if test="vo.sailTime != null">
+            AND DATE(v.start_time) = #{vo.sailTime}
+        </if>
+        <if test="vo.travelAgency != null and vo.travelAgency != ''">
+            AND o.source_name LIKE CONCAT('%', #{vo.travelAgency}, '%')
+        </if>
+        <if test="vo.shipId != null">
+            AND v.ship_id = #{vo.shipId}
+        </if>
+        <if test="vo.routeName != null and vo.routeName != ''">
+            AND r.name LIKE CONCAT('%', #{vo.routeName}, '%')
+        </if>
+        <if test="vo.roomTypeName != null and vo.roomTypeName != ''">
+            AND EXISTS (
+                SELECT 1 FROM trade_order_room_model orm2
+                WHERE orm2.order_id = o.id AND orm2.deleted = 0
+                AND orm2.room_model_name LIKE CONCAT('%', #{vo.roomTypeName}, '%')
+            )
+        </if>
+        ORDER BY o.create_time DESC
+    </select>
+
+</mapper>