111
k94314517
2025-03-19 19fd7785705f30d25c6c8e44b9356cc585af68cd
111
已添加2个文件
已修改12个文件
376 ■■■■ 文件已修改
server/platform/src/main/java/com/doumee/api/business/GoodsorderController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/annotation/excel/ExcelExporter.java 64 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/utils/DateUtil.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/DiscountMember.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/Goodsorder.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/vo/BikeIncomeDetailReportVO.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/vo/BikeIncomeReportVO.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/vo/GoodsorderExportVO.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/web/response/RidesDetailResponse.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/GoodsorderService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/DiscountMemberServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java 147 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/WxBillServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/task/ScheduleTool.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/platform/src/main/java/com/doumee/api/business/GoodsorderController.java
@@ -10,6 +10,7 @@
import com.doumee.core.utils.DateUtil;
import com.doumee.dao.business.model.Goodsorder;
import com.doumee.dao.business.model.WxBillDetail;
import com.doumee.dao.business.vo.BikeIncomeReportVO;
import com.doumee.dao.business.vo.DiscountGoodsorderExportVO;
import com.doumee.dao.business.vo.GoodsorderExportVO;
import com.doumee.dao.business.vo.GoodsorderTotalDataVO;
@@ -31,6 +32,7 @@
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@@ -94,6 +96,7 @@
        return ApiResponse.success(goodsorderService.findPage(pageWrap));
    }
    @ApiOperation("线上交易汇总数据接口")
    @PostMapping("/getTotalData")
    @RequiresPermissions("business:goodsorder:query")
@@ -102,6 +105,8 @@
        pageWrap.setEndDate(pageWrap.getEndDate() != null ? pageWrap.getEndDate():pageWrap.getStartDate());
        return ApiResponse.success(goodsorderService.getTotalData(pageWrap));
    }
    @ApiOperation("订单列表-导出Excel")
    @PostMapping("/exportExcel")
@@ -135,6 +140,7 @@
    public ApiResponse<PageData<GoodsorderExportVO>> findPageAccountDetail(@RequestBody PageWrap<Goodsorder> pageWrap) {
            return ApiResponse.success(goodsorderService.findAccountDetailPage(pageWrap));
    }
    @ApiOperation("收款明细(微信对账明细)_导出Excel")
    @PostMapping("/exportAccountDetailExcel")
    @RequiresPermissions("business:goodsorder:exportExcel")
@@ -186,4 +192,19 @@
    public ApiResponse<GoodsorderCanBanlanceDTO> getGoodsorderCanBanlanceDTO(@RequestParam String orderId){
        return ApiResponse.success(goodsorderService.getGoodsorderCanBanlanceDTO(orderId));
    }
    @ApiOperation("车型收入分析")
    @PostMapping("/getBikeIncomeReportVOList")
    public ApiResponse<List<List<String>>> getBikeIncomeReportVOList (@RequestBody Goodsorder goodsorder) {
        return ApiResponse.success(goodsorderService.getBikeIncomeReportVOList(goodsorder.getStartDate(),goodsorder.getEndDate()));
    }
    @ApiOperation("车型收入分析-导出Excel")
    @PostMapping("/bikeIncomeExportExcel")
    public void exportExcel (@RequestBody Goodsorder goodsorder, HttpServletResponse response) {
        goodsorderService.excel(goodsorder.getStartDate(),goodsorder.getEndDate(),response);
    }
}
server/services/src/main/java/com/doumee/core/annotation/excel/ExcelExporter.java
@@ -1,5 +1,6 @@
package com.doumee.core.annotation.excel;
import com.doumee.core.constants.Constants;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.dao.business.model.Goodsorder;
@@ -168,6 +169,21 @@
            }
        }
    }
//    public void exportList (List<List<String>> data, String fileName, String sheetName, HttpServletResponse response) {
//        try {
//            String encodeFileName = URLEncoder.encode(fileName, Charset.forName("UTF-8").toString()) + ".xlsx";
//            response.setHeader("Content-Disposition","attachment;filename=" + encodeFileName);
//            response.setContentType("application/octet-stream");
//            response.setHeader("eva-opera-type", "download");
//            response.setHeader("eva-download-filename", encodeFileName);
//            this.exportList(data, sheetName, response.getOutputStream());
//        } catch (IOException e) {
//            throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e);
//        }
//    }
    /**
     * å¯¼å‡ºåˆ°æŒ‡å®šè¾“出流
     * @param os è¾“出流
@@ -181,27 +197,47 @@
            sheet.createFreezePane(0, 1);
            Row header = sheet.createRow(0);
            CellStyle hstyle = configHeaderCellStatic(sxssfWorkbook);
            CellStyle cstyle = configCellStatic(sxssfWorkbook);
            List<String> headerList =dataList.get(0);
            for (int i = 0; i < headerList.size(); i++) {
            for (int i = 0; i < dataList.size(); i++) {
                Cell cell = header.createCell(i);
                cell.setCellValue(headerList.get(i));
                cell.setCellValue(dataList.get(i).get(Constants.ZERO));
                // åˆ—宽设置
                sheet.setColumnWidth(i, headerList.get(i).length() * 2 * 256);
                sheet.setColumnWidth(i, dataList.get(i).get(Constants.ZERO).length() * 2 * 256);
                // è®¾ç½®åˆ—头单元格
                cell.setCellStyle(hstyle);
            }
            // åˆ›å»ºæ•°æ®è®°å½•
            for (int rowIndex = 1; rowIndex < dataList.size(); rowIndex++) {
                Row row = sheet.createRow(rowIndex );
                List<String> rowList = dataList.get(rowIndex);
                for (int i = 0; i < rowList.size(); i++) {
                    Cell cell = row.createCell(i);
                    cell.setCellValue(rowList.get(i));
                    // åˆ—宽设置
                    cell.setCellStyle(cstyle);
            //总行数
            Integer rowSize = dataList.get(Constants.ZERO).size();
            //总列数
            Integer columnSize = dataList.size();
            for (int i = 1; i < rowSize; i++) {
                Row row = sheet.createRow(i);
                for (int j = 0; j < columnSize; j++) {
                    Cell cell = row.createCell(j);
                    cell.setCellValue(dataList.get(j).get(i));
                }
            }
//
//            List<String> headerList =dataList.get(0);
//            for (int i = 0; i < headerList.size(); i++) {
//                Cell cell = header.createCell(i);
//                cell.setCellValue(headerList.get(i));
//                // åˆ—宽设置
//                sheet.setColumnWidth(i, headerList.get(i).length() * 2 * 256);
//                // è®¾ç½®åˆ—头单元格
//                cell.setCellStyle(hstyle);
//            }
//            // åˆ›å»ºæ•°æ®è®°å½•
//            for (int rowIndex = 1; rowIndex < dataList.size(); rowIndex++) {
//                Row row = sheet.createRow(rowIndex );
//                List<String> rowList = dataList.get(rowIndex);
//                for (int i = 0; i < rowList.size(); i++) {
//                    Cell cell = row.createCell(i);
//                    cell.setCellValue(rowList.get(i));
//                    // åˆ—宽设置
//                    cell.setCellStyle(cstyle);
//                }
//            }
            sxssfWorkbook.write(os);
            os.close();
        } catch (Exception e) {
server/services/src/main/java/com/doumee/core/utils/DateUtil.java
@@ -69,6 +69,30 @@
    }
    public static List<Date> getDateList(Date dBegin, Date dEnd) {
        int i = 1;
        //日期工具类准备
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        //设置开始时间
        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(dBegin);
        int weekNumber = calBegin.get(Calendar.DAY_OF_WEEK) - 1;
        //设置结束时间
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(dEnd);
        //装返回的日期集合容器
        List<Date> dateList = new ArrayList<Date>();
        dateList.add(dBegin);
        //将第一个月添加里面去
        while (dEnd.after(calBegin.getTime())) {
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            Date date =  calBegin.getTime();
            dateList.add(date);
        }
        return dateList;
    }
    public static Date StringToDateFormat(String DATE,String format) {
        if(StringUtils.isBlank(DATE)){
server/services/src/main/java/com/doumee/dao/business/model/DiscountMember.java
@@ -28,6 +28,7 @@
    @ApiModelProperty(value = "创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @ExcelColumn(name="创建时间",index = 8,width = 16,dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date createDate;
    @ApiModelProperty(value = "创建人")
@@ -162,4 +163,14 @@
    @ApiModelProperty(value = "操作记录")
    @TableField(exist = false)
    private List<DiscountLog> optLogList;
    @ApiModelProperty(value = "查询开始日期(包含)", example = "2023-10-01 15:12:01")
    @TableField(exist = false)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date startCreateDate;
    @ApiModelProperty(value = "查询截止日期(包含)", example = "2023-10-09 15:12:05")
    @TableField(exist = false)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date endCreateDate;
}
server/services/src/main/java/com/doumee/dao/business/model/Goodsorder.java
@@ -103,6 +103,8 @@
    private String closeUserId;
    @ApiModelProperty(value = "结算类型 0用户自行结算 1平台人工强制结算 2系统自动结算")
    private Integer closeType;
    @ApiModelProperty(value = "结算车型编码")
    private String paramId;
    @ApiModelProperty(value = "用户openid" )
    @TableField(exist = false)
    @ExcelColumn(name="用户",index = 1 ,width = 10,align = HorizontalAlignment.CENTER)
@@ -123,11 +125,12 @@
    @ExcelColumn(name="退押金(元)",index = 6,width = 10,align = HorizontalAlignment.CENTER)
    private BigDecimal refundMoney;
    @ApiModelProperty(value = "骑行卡抵扣(分)")
    @ExcelColumn(name="优惠金额",index = 10,width = 10,align = HorizontalAlignment.CENTER)
    @TableField(exist = false)
    private BigDecimal discountMoney;
    @ApiModelProperty(value = "最后退款时间")
    @TableField(exist = false)
    @ExcelColumn(name="退款结算时间",index = 9,width = 10,align = HorizontalAlignment.CENTER,dateFormat = "yyyy-MM-dd HH:mm:ss")
    @ExcelColumn(name="退款时间",index = 9,width = 10,align = HorizontalAlignment.CENTER,dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date refundDate;
    @ApiModelProperty(value = "最近骑行状态")
    @TableField(exist = false)
@@ -137,7 +140,6 @@
    private Integer closeStatus;
    @ApiModelProperty(value = "操作人")
    @ExcelColumn(name="操作人",index = 9,width = 10,align = HorizontalAlignment.CENTER)
    @TableField(exist = false)
    private String refundUserName;
@@ -145,4 +147,9 @@
    @TableField(exist = false)
    private String discountName;
    @ApiModelProperty(value = "骑行类型")
    @ExcelColumn(name="订单类型",index = 11,width = 10,valueMapping = "3=单车类型;4=电车类型;",align = HorizontalAlignment.CENTER)
    @TableField(exist = false)
    private Integer bikeType;
}
server/services/src/main/java/com/doumee/dao/business/vo/BikeIncomeDetailReportVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.doumee.dao.business.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
 * è®¢å•信息表
 * @author æ±Ÿè¹„蹄
 * @date 2023/09/27 18:06
 */
@Data
@ApiModel("车型收入分析")
public class BikeIncomeDetailReportVO {
    @ApiModelProperty(value = "收入金额")
    private String totalAmount;
    @ApiModelProperty(value = "日期值")
    private String dateStr;
}
server/services/src/main/java/com/doumee/dao/business/vo/BikeIncomeReportVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.doumee.dao.business.vo;
import com.doumee.core.annotation.excel.ExcelColumn;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
 * è®¢å•信息表
 * @author æ±Ÿè¹„蹄
 * @date 2023/09/27 18:06
 */
@Data
@ApiModel("车型收入分析")
public class BikeIncomeReportVO {
    @ApiModelProperty(value = "车型名称")
    private String paramName;
    @ApiModelProperty(value = "车型主键")
    private String paramId;
//    @ApiModelProperty(value = "行数据收入列表")
//    private List<BikeIncomeDetailReportVO> bikeIncomeDetailReportVOList;
    @ApiModelProperty(value = "行数据收入列表")
    private List<String> dataList;
}
server/services/src/main/java/com/doumee/dao/business/vo/GoodsorderExportVO.java
@@ -57,4 +57,11 @@
    @ExcelColumn(name="退款时间",width = 10,index = 5,align = HorizontalAlignment.CENTER,dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date refundDate;
    @ApiModelProperty(value = "骑行类型")
    @ExcelColumn(name="订单类型",index = 8,width = 10,valueMapping = "1=套餐订单;3=自行车订单;4=电动车订单;",align = HorizontalAlignment.CENTER)
    private Integer bikeType;
    @ApiModelProperty(value = "交易类型 0租车押金 1套餐卡购买")
    private Integer type;
}
server/services/src/main/java/com/doumee/dao/business/web/response/RidesDetailResponse.java
@@ -35,6 +35,9 @@
    @ApiModelProperty(value = "抵扣金额")
    private BigDecimal disCountMoney;
    @ApiModelProperty(value = "车辆类型编码")
    private String paramId;
    @ApiModelProperty(value = "骑行记录")
    private List<MemberRidesResponse> memberRidesResponseList;
server/services/src/main/java/com/doumee/service/business/GoodsorderService.java
@@ -8,6 +8,7 @@
import com.doumee.dao.business.model.DiscountMember;
import com.doumee.dao.business.model.Goodsorder;
import com.doumee.dao.business.model.MemberRides;
import com.doumee.dao.business.vo.BikeIncomeReportVO;
import com.doumee.dao.business.vo.GoodsorderExportVO;
import com.doumee.dao.business.vo.GoodsorderTotalDataVO;
import com.doumee.dao.business.web.request.BackElecBikeRequest;
@@ -20,7 +21,9 @@
import com.wechat.pay.java.service.refund.model.RefundNotification;
import io.swagger.models.auth.In;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
@@ -212,4 +215,8 @@
    DiscountMember getUseDiscount(String memberId, Integer driveTime,Integer type);
    void autCancel();
    List<List<String>> getBikeIncomeReportVOList(Date startDate , Date endDate);
    void excel(Date startDate , Date endDate, HttpServletResponse response);
}
server/services/src/main/java/com/doumee/service/business/impl/DiscountMemberServiceImpl.java
@@ -11,10 +11,7 @@
import com.doumee.dao.business.DiscountLogMapper;
import com.doumee.dao.business.DiscountMemberMapper;
import com.doumee.dao.business.join.DiscountMemberJoinMapper;
import com.doumee.dao.business.model.Discount;
import com.doumee.dao.business.model.DiscountLog;
import com.doumee.dao.business.model.DiscountMember;
import com.doumee.dao.business.model.Member;
import com.doumee.dao.business.model.*;
import com.doumee.dao.business.web.request.DiscountMemberDTO;
import com.doumee.dao.system.model.SystemUser;
import com.doumee.service.business.DiscountMemberService;
@@ -147,6 +144,8 @@
                .like(StringUtils.isNotBlank(model.getName()),DiscountMember::getName,model.getName())
                .like(StringUtils.isNotBlank(model.getOpenid()),Member::getOpenid,model.getOpenid())
                .eq(Objects.nonNull(model.getStatus()),DiscountMember::getStatus,model.getStatus())
                .ge(Objects.nonNull(model.getStartCreateDate()),DiscountMember::getCreateDate, Utils.Date.getStart(model.getStartCreateDate()))
                .le(Objects.nonNull(model.getEndCreateDate()),DiscountMember::getCreateDate, Utils.Date.getStart(model.getEndCreateDate()))
                .ne(DiscountMember::getStatus,Constants.TWO)
                .orderByDesc(DiscountMember::getCode);
        return PageData.from(discountMemberJoinMapper.selectJoinPage(page, DiscountMember.class,queryWrapper));
@@ -249,4 +248,8 @@
        QueryWrapper<DiscountMember> wrapper = new QueryWrapper<>(discountMember);
        return discountMemberMapper.selectCount(wrapper);
    }
}
server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java
@@ -6,6 +6,7 @@
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.doumee.core.annotation.excel.ExcelExporter;
import com.doumee.core.constants.Constants;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.core.constants.Constants;
@@ -28,6 +29,8 @@
import com.doumee.dao.business.model.Goodsorder;
import com.doumee.dao.business.model.Member;
import com.doumee.dao.business.model.MemberRides;
import com.doumee.dao.business.vo.BikeIncomeDetailReportVO;
import com.doumee.dao.business.vo.BikeIncomeReportVO;
import com.doumee.dao.business.vo.GoodsorderExportVO;
import com.doumee.dao.business.vo.GoodsorderTotalDataVO;
import com.doumee.dao.business.web.request.*;
@@ -58,10 +61,14 @@
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.sql.Ref;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
@@ -199,7 +206,9 @@
            MPJLambdaWrapper<Goodsorder> queryWrapper = new MPJLambdaWrapper<>();
            queryWrapper.selectAll(Goodsorder.class);
            queryWrapper.selectAs(Member::getOpenid, Goodsorder::getOpenid);
            queryWrapper.selectAs(BaseParam::getType, Goodsorder::getBikeType);
            queryWrapper.leftJoin(Member.class, Member::getId  ,Goodsorder::getMemberId);
            queryWrapper.leftJoin(BaseParam.class, BaseParam::getId  ,Goodsorder::getParamId);
            queryWrapper.select("(select max(r.done_date) from refund r where r.obj_id=t.id  and r.status=2 ) as refund_date");
            queryWrapper.select("(select sum(r.money) from refund r where r.obj_id=t.id and r.status=2) as refund_money");
            //时间段筛选
@@ -213,6 +222,9 @@
            queryWrapper.eq(Goodsorder::getPayStatus,Constants.ONE);
            queryWrapper.orderByAsc(Goodsorder::getPayDate);
            goodsorderExportVOIPage = goodsorderJoinMapper.selectJoinPage(page, GoodsorderExportVO.class, queryWrapper);
        }else{
            MPJLambdaWrapper<Refund> queryWrapper = new MPJLambdaWrapper<>();
            queryWrapper.selectAs(Refund::getMoney,GoodsorderExportVO::getRefundMoney);
@@ -240,6 +252,7 @@
        if (!CollectionUtils.isEmpty(goodsorderExportVOIPage.getRecords())){
            goodsorderExportVOIPage.getRecords().forEach(s->{
                s.setBikeType(s.getType()!=Constants.ZERO?s.getBikeType():Constants.ONE);
                s.setMoney(Constants.translateMoney(s.getMoney()));
                s.setRefundMoney(Constants.translateMoney(s.getRefundMoney()));
                s.setCloseMoney(Constants.translateMoney(s.getCloseMoney()).compareTo(s.getMoney()) > 0 ? s.getMoney() : Constants.translateMoney(s.getCloseMoney()));
@@ -296,11 +309,13 @@
        queryWrapper.selectAll(Goodsorder.class);
        queryWrapper.selectAs(Member::getOpenid, Goodsorder::getOpenid);
        queryWrapper.selectAs(DiscountMember::getName, Goodsorder::getDiscountName);
        queryWrapper.selectAs(BaseParam::getType, Goodsorder::getBikeType);
        queryWrapper.leftJoin(Member.class, Member::getId  ,Goodsorder::getMemberId);
        queryWrapper.leftJoin(DiscountMember.class, DiscountMember::getGoodsorderId  ,Goodsorder::getId);
//        queryWrapper.select("(select r.name from discount_member r where r.isdeleted=0  and r.goodsorder_id=t.id limit 1) as discountName");
        queryWrapper.leftJoin(BaseParam.class, BaseParam::getId  ,Goodsorder::getParamId);
        queryWrapper.select("(select max(r.done_date) from refund r where r.obj_id=t.id  and  r.status in(0,2)) as refund_date");
        queryWrapper.select("(select sum(r.money) from refund r where r.obj_id=t.id and r.status in(0,2)) as refund_money");
        queryWrapper.select("(select  sum(d.ride_price)  from discount_log d where d.goodsorder_id=t.id and d.type = 0) as discountMoney");
        //时间段筛选
        if (Objects.nonNull(model.getStartDate())){
            queryWrapper.ge(Goodsorder::getPayDate, Utils.Date.getStart(model.getStartDate()));
@@ -333,6 +348,8 @@
        queryWrapper.select("(select  sum(er.discount_price) from member_rides  er  where er.ordre_id=t.id and er.isdeleted=0) as discountMoney," +
                "(select  er.status from member_rides  er  where er.ordre_id=t.id order by er.create_date desc limit 1) as memberRidesStatus");
        queryWrapper.select("( select s.realname from refund r left join system_user s on r.creator = s.id where r.obj_id = t.id order by r.id desc  limit 1  ) ",Goodsorder::getRefundUserName);
        if(Objects.nonNull(pageWrap.getModel().getCloseStatus()) && pageWrap.getModel().getCloseStatus().equals(Constants.ZERO)){
            queryWrapper.ne(Goodsorder::getStatus,Constants.GOODSORDER_STATUS.CLOSE.getKey());
@@ -627,6 +644,7 @@
                freeTime = Integer.parseInt(systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME, Constants.FREE_RENT_TIME).getCode());
            }catch (Exception e){
            }
            closeMoney = getCloseMoneyByRides(memberRides,freeTime,true,goodsorder.getMoney(),goodsorder.getMemberId(),true).getAmount();
            //实际结算价格,记录在最高车型记录上
//            memberRides.get(0).setActualPrice(closeMoney);
@@ -674,6 +692,15 @@
                memberRidesJoinMapper.updateById(up);
            }
        }
        int durationSum = 0;
        int freeTime = 0;
        try {
            freeTime = Integer.parseInt(systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME, Constants.FREE_RENT_TIME).getCode());
        }catch (Exception e){
        }
        //最高价格车型的骑行记录
        MemberRides topRides = this.getMaxRides(memberRides,durationSum,freeTime,true);
//        BigDecimal closeMoney =( Constants.formatDecimalNum(goodsorder.getMoney()).subtract(refund.getMoney()));
        //退款乐行
//       int type =Constants.formatIntegerNum(refund.getType());
@@ -681,6 +708,7 @@
        update.setId(goodsorder.getId());
        update.setStatus(Constants.GOODSORDER_STATUS.CLOSE.getKey());
        update.setCloseMoney(closeMoney);
        update.setParamId(Objects.nonNull(topRides)?topRides.getParamId():null);
        update.setCloseStatus(Constants.ONE);
        update.setCloseDate(new Date());
        update.setCloseInfo(Constants.REFUND_TYPE.get(type).getInfo());
@@ -717,6 +745,23 @@
        transactionsMapper.insert(transactions);
        //修改订单信息
        goodsorderMapper.updateById(update);
    }
    public MemberRides getMaxRides(List<MemberRides> memberRides,Integer durationSum,Integer freeTime,boolean isClose){
        MemberRides topRides =null;
        for(MemberRides rides : memberRides){
            if ( isClose && Constants.MEMBER_RIDES_STATUS.BACK_CYCLING.getKey()!=(Constants.formatIntegerNum(rides.getStatus()))){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"当前订单有未完成的骑行,无法强制结算");
            }
            durationSum += Constants.formatIntegerNum(rides.getDuration());//累计骑行(计费)时长
            if(durationSum-freeTime > 0 ){//只算超出免费时长的数据
                if(topRides == null ||( Constants.formatIntegerNum(topRides.getSortnum())<Constants.formatIntegerNum(rides.getSortnum())
                        && Constants.formatIntegerNum(rides.getDuration())>0)){
                    topRides = rides;
                }
            }
        }
        return topRides;
    }
    /**
     * é€€æ¬¾æˆåŠŸå›žè°ƒ
@@ -797,21 +842,8 @@
        ridesDetailResponse.setHaveDisCount(Constants.ZERO);
        BigDecimal closeMoney = new BigDecimal(0.00);
        int durationSum = 0;
        MemberRides topRides =null;
        //取最高车型计算方案结算订单
        for(MemberRides rides : memberRides){
            if ( isClose && Constants.MEMBER_RIDES_STATUS.BACK_CYCLING.getKey()!=(Constants.formatIntegerNum(rides.getStatus()))){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"当前订单有未完成的骑行,无法强制结算");
            }
            durationSum += Constants.formatIntegerNum(rides.getDuration());//累计骑行(计费)时长
            if(durationSum-freeTime > 0 ){//只算超出免费时长的数据
                if(topRides == null ||( Constants.formatIntegerNum(topRides.getSortnum())<Constants.formatIntegerNum(rides.getSortnum())
                        && Constants.formatIntegerNum(rides.getDuration())>0)){
                    topRides = rides;
                }
            }
        }
        //最高价格车型的骑行记录
        MemberRides topRides = this.getMaxRides(memberRides,durationSum,freeTime,isClose);
        //计算应付金额
        if( topRides != null){
@@ -827,6 +859,8 @@
                }
            }
            topRides.setActualPrice(closeMoney);
            //2025å¹´3月18日11:28:38 è¿”回骑行价格最高的车型
            ridesDetailResponse.setParamId(topRides.getParamId());
        } 
        //查询是否存在套餐信息
        DiscountMember discountMember = this.getUseDiscount(memberId,durationSum,Objects.nonNull(topRides)?topRides.getType():null);
@@ -1641,4 +1675,85 @@
        );
    }
    @Override
    public List<List<String>> getBikeIncomeReportVOList(Date startDate ,Date endDate){
        if( (Objects.isNull(startDate)||Objects.isNull(endDate))
        || startDate.getTime()>endDate.getTime()
        || DateUtil.daysBetweenDates(endDate,startDate) > 30
        )
        {
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        System.out.println( DateUtil.daysBetweenDates(endDate,startDate));
        //获取所有车型信息
        List<BaseParam> baseParamList = baseParamMapper.selectList(new QueryWrapper<BaseParam>().lambda().eq(BaseParam::getIsdeleted,Constants.ZERO)
                .in(BaseParam::getType,Constants.THREE,Constants.FOUR)
                .orderByAsc(BaseParam::getType,BaseParam::getSortnum)
        );
        //获取2个日期下所有天数
        List<Date> dateList = DateUtil.getDateList(startDate,endDate);
        //查询日期内的所有数据
        List<Goodsorder> goodsorderList = goodsorderMapper.selectList(new QueryWrapper<Goodsorder>().lambda().eq(Goodsorder::getType,Constants.ZERO)
                .eq(Goodsorder::getIsdeleted,Constants.ZERO)
                .eq(Goodsorder::getStatus,Constants.FOUR)
                .isNotNull(Goodsorder::getParamId)
                .ge(Goodsorder::getPayDate, Utils.Date.getStart(startDate))
                .le( Goodsorder::getPayDate, Utils.Date.getEnd(endDate))
        );
        List<List<String>> parentList = new ArrayList<>();
        for (BaseParam baseParam:baseParamList) {
            List<String> dataChildList = new ArrayList<>();
            dataChildList.add(baseParam.getName()+"(元)");
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (Date date:dateList) {
                BigDecimal amount = goodsorderList.stream()
                        .filter(i->StringUtils.isNotBlank(i.getParamId())&&DateUtil.getShortDateStr(date).equals(DateUtil.getShortDateStr(i.getCreateDate()))&&baseParam.getId().equals(i.getParamId()))
                        .map(i->i.getCloseMoney()).reduce(BigDecimal.ZERO,BigDecimal::add);
                dataChildList.add(amount.toString());
                totalAmount  = amount.add(totalAmount);
            }
            BikeIncomeDetailReportVO detail = new BikeIncomeDetailReportVO();
            dataChildList.add("ï¿¥"+totalAmount);
            parentList.add(dataChildList);
        }
        List<String> dataStrList = new ArrayList<>();
        dataStrList.add("日期");
        for (Date date:dateList) {
            dataStrList.add(DateUtil.getShortDateStr(date));
        }
        dataStrList.add("总计");
        parentList.add(0,dataStrList);
        return parentList;
    }
    @Override
    public void excel(Date startDate , Date endDate, HttpServletResponse response){
        List<List<String>> data = this.getBikeIncomeReportVOList(startDate,endDate);
        try {
            String fileName = "车型收入分析_"+System.currentTimeMillis();
            String encodeFileName = URLEncoder.encode(fileName, Charset.forName("UTF-8").toString()) + ".xlsx";
            response.setHeader("Content-Disposition","attachment;filename=" + encodeFileName);
            response.setContentType("application/octet-stream");
            response.setHeader("eva-opera-type", "download");
            response.setHeader("eva-download-filename", encodeFileName);
            ExcelExporter.exportList(data, fileName, response.getOutputStream());
        } catch (IOException e) {
            throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e);
        }
    }
}
server/services/src/main/java/com/doumee/service/business/impl/WxBillServiceImpl.java
@@ -273,6 +273,7 @@
        bill.setDiscountRefundFee(new BigDecimal(0.00));
        bill.setDiscountRefundCmmsAmt(new BigDecimal(0.00));
        bill.setBikeRefundCmmsAmt(new BigDecimal(0.00));
        bill.setDiscountFee(new BigDecimal(0.00));
        return bill;
    }
    @Override
server/web/src/main/java/com/doumee/task/ScheduleTool.java
@@ -43,12 +43,12 @@
     * ç«™ç‚¹è½¦è¾†æ»¡æž¶çŽ‡é¢„è­¦
     * @throws Exception
     */
//    @Scheduled(fixedDelay = 1000L *20L )
//    public void reSubMqtt() throws Exception {
//        log.info("=====================检查是否需要重新订阅===========start============");
//        MqttClientInit.isSubClientValid();
//        log.info("=====================检查是否需要重新订阅===========end============");
//    }
    @Scheduled(fixedDelay = 1000L *20L )
    public void reSubMqtt() throws Exception {
        log.info("=====================检查是否需要重新订阅===========start============");
        MqttClientInit.isSubClientValid();
        log.info("=====================检查是否需要重新订阅===========end============");
    }
    @Scheduled(fixedDelay = 1000L * 100L )