ソースを参照

订单导出优化;增加sftp工具类;增加多数据源配置和sftp配置

wanxl 1 年間 前
コミット
0f5ef22da3

+ 5 - 0
pom.xml

@@ -423,6 +423,11 @@
             <version>3.1.1</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>com.jcraft</groupId>
+            <artifactId>jsch</artifactId>
+            <version>0.1.54</version>
+        </dependency>
 
         <!--<dependency>-->
         <!--<groupId>com.baidu.aip</groupId>-->

+ 230 - 0
src/main/java/com/sqx/common/utils/SftpUtil.java

@@ -0,0 +1,230 @@
+package com.sqx.common.utils;
+
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.jcraft.jsch.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.*;
+import java.util.Properties;
+
+/**
+ * 类说明 sftp工具类
+ */
+@Component
+public class SftpUtil {
+    private transient Logger log = LoggerFactory.getLogger(this.getClass());
+
+    private ChannelSftp sftp;
+
+    private Session session;
+    /** SFTP 登录用户名*/
+    @Value("${sftp.username}")
+    private String username;
+    /** SFTP 登录密码*/
+    @Value("${sftp.password}")
+    private String password;
+    /** 私钥 */
+    private String privateKey;
+    /** SFTP 服务器地址IP地址*/
+    @Value("${sftp.host}")
+    private String host;
+    /** SFTP 端口*/
+    @Value("${sftp.port}")
+    private int port;
+
+
+    /**
+     * 构造基于密码认证的sftp对象
+     */
+    public SftpUtil(String username, String password, String host, int port) {
+        this.username = username;
+        this.password = password;
+        this.host = host;
+        this.port = port;
+    }
+
+    /**
+     * 构造基于秘钥认证的sftp对象
+     */
+    public SftpUtil(String username, String host, int port, String privateKey) {
+        this.username = username;
+        this.host = host;
+        this.port = port;
+        this.privateKey = privateKey;
+    }
+
+    public SftpUtil(){}
+
+
+    /**
+     * 连接sftp服务器
+     */
+    public void login(){
+        try {
+            JSch jsch = new JSch();
+            if (privateKey != null) {
+                jsch.addIdentity(privateKey);// 设置私钥
+            }
+
+            session = jsch.getSession(username, host, port);
+
+            if (password != null) {
+                session.setPassword(password);
+            }
+            Properties config = new Properties();
+            config.put("StrictHostKeyChecking", "no");
+
+            session.setConfig(config);
+            session.connect();
+
+            Channel channel = session.openChannel("sftp");
+            channel.connect();
+
+            sftp = (ChannelSftp) channel;
+        } catch (JSchException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 关闭连接 server
+     */
+    public void logout(){
+        try{
+            if (sftp != null) {
+                if (sftp.isConnected()) {
+                    sftp.disconnect();
+                }
+            }
+            if (session != null) {
+                if (session.isConnected()) {
+                    session.disconnect();
+                }
+            }
+        }catch (Exception e){
+            log.error("sftp登出失败", e);
+        }
+    }
+
+
+    /**
+     * 将输入流的数据上传到sftp作为文件。文件完整路径=basePath+directory
+     * @param directory  上传到该目录
+     * @param sftpFileName  sftp端文件名
+     * @param input   输入流
+     */
+    public void upload(String directory, String sftpFileName, InputStream input) throws SftpException{
+        try {
+            String home = sftp.getHome();
+            sftp.cd(home);
+            //sftp.cd(basePath);
+            sftp.cd(directory);
+        } catch (SftpException e) {
+            //目录不存在,则创建文件夹
+            String [] dirs=directory.split("/");
+            String tempPath=sftp.getHome();
+            for(String dir:dirs){
+                if(null== dir || "".equals(dir)) continue;
+                tempPath+="/"+dir;
+                try{
+                    sftp.cd(tempPath);
+                }catch(SftpException ex){
+                    sftp.mkdir(tempPath);
+                    sftp.cd(tempPath);
+                }
+            }
+        }
+        sftp.put(input, sftpFileName);  //上传文件
+    }
+
+
+    /**
+     * 下载文件。
+     * @param directory 下载目录
+     * @param downloadFile 下载的文件
+     * @param saveFile 存在本地的路径
+     */
+    public void download(String directory, String downloadFile, File saveFile) throws SftpException, FileNotFoundException{
+        String home = sftp.getHome();
+        sftp.cd(home);
+        if (directory != null && !"".equals(directory)) {
+            sftp.cd(directory);
+        }
+        sftp.get(downloadFile, new FileOutputStream(saveFile));
+    }
+    /**
+     * 下载文件。
+     * @param directory 下载目录
+     * @param downloadFile 下载的文件
+     * @param outputStream 输出流
+     */
+    public void downloadStream(String directory, String downloadFile,OutputStream outputStream) throws SftpException, FileNotFoundException{
+        String home = sftp.getHome();
+        sftp.cd(home);
+        if (directory != null && !"".equals(directory)) {
+            sftp.cd(directory);
+        }
+        sftp.get(downloadFile,outputStream);
+    }
+
+    /**
+     * 下载文件
+     * @param directory 下载目录
+     * @param downloadFile 下载的文件名
+     * @return 字节数组
+     */
+    public byte[] download(String directory, String downloadFile) throws SftpException, IOException{
+        if (directory != null && !"".equals(directory)) {
+            sftp.cd(directory);
+        }
+        InputStream is = sftp.get(downloadFile);
+
+        byte[] fileData = IOUtils.toByteArray(is);
+
+        return fileData;
+    }
+
+
+    /**
+     * 删除文件
+     * @param directory 要删除文件所在目录
+     * @param deleteFile 要删除的文件
+     */
+    public void delete(String directory, String deleteFile) throws SftpException{
+        sftp.cd(directory);
+        sftp.rm(deleteFile);
+    }
+
+    public ChannelSftp getSftp() {
+        return sftp;
+    }
+
+    public boolean isConnected(){
+        return sftp.isConnected();
+    }
+
+    public boolean mkdir(String dir){
+        try{
+            sftp.mkdir(dir);
+            return true;
+        }catch (Exception e){
+            log.error("目录创建失败: ", e);
+            return false;
+        }
+    }
+
+    //上传文件测试
+    public static void main(String[] args) throws SftpException, IOException {
+        SftpUtil sftp = new SftpUtil("export", "Waimai2024#", "172.16.20.108", 22);
+        sftp.login();
+        File file = new File("E:\\chen\\Desktop\\fsdownload\\text.log");
+        InputStream is = new FileInputStream(file);
+
+        sftp.upload("/", "text.log", is);
+        sftp.download("/","test_sftp.jpg",file);
+        sftp.logout();
+    }
+}

+ 11 - 5
src/main/java/com/sqx/datasource/config/DynamicDataSourceConfig.java

@@ -2,7 +2,7 @@ package com.sqx.datasource.config;
 
 import com.alibaba.druid.pool.DruidDataSource;
 import com.sqx.datasource.properties.DataSourceProperties;
-import com.sqx.datasource.properties.DynamicDataSourceProperties;
+//import com.sqx.datasource.properties.DynamicDataSourceProperties;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -16,16 +16,21 @@ import java.util.Map;
  * 配置多数据源
  */
 @Configuration
-@EnableConfigurationProperties(DynamicDataSourceProperties.class)
+//@EnableConfigurationProperties(DynamicDataSourceProperties.class)
 public class DynamicDataSourceConfig {
-    @Autowired
-    private DynamicDataSourceProperties properties;
+//    @Autowired
+//    private DynamicDataSourceProperties properties;
 
     @Bean
     @ConfigurationProperties(prefix = "spring.datasource.druid")
     public DataSourceProperties dataSourceProperties() {
         return new DataSourceProperties();
     }
+    @Bean
+    @ConfigurationProperties(prefix = "dynamic")
+    public DataSourceProperties getDatasource() {
+        return new DataSourceProperties();
+    }
 
     @Bean
     public DynamicDataSource dynamicDataSource(DataSourceProperties dataSourceProperties) {
@@ -40,7 +45,8 @@ public class DynamicDataSourceConfig {
     }
 
     private Map<Object, Object> getDynamicDataSource(){
-        Map<String, DataSourceProperties> dataSourcePropertiesMap = properties.getDatasource();
+        Map<String, DataSourceProperties> dataSourcePropertiesMap = new HashMap<>();
+        dataSourcePropertiesMap.put("dynamic",this.getDatasource());
         Map<Object, Object> targetDataSources = new HashMap<>(dataSourcePropertiesMap.size());
         dataSourcePropertiesMap.forEach((k, v) -> {
             DruidDataSource druidDataSource = DynamicDataSourceFactory.buildDruidDataSource(v);

+ 15 - 15
src/main/java/com/sqx/datasource/properties/DynamicDataSourceProperties.java

@@ -5,18 +5,18 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
-/**
- * 多数据源属性
- */
-@ConfigurationProperties(prefix = "dynamic")
-public class DynamicDataSourceProperties {
-    private Map<String, DataSourceProperties> datasource = new LinkedHashMap<>();
-
-    public Map<String, DataSourceProperties> getDatasource() {
-        return datasource;
-    }
-
-    public void setDatasource(Map<String, DataSourceProperties> datasource) {
-        this.datasource = datasource;
-    }
-}
+///**
+// * 多数据源属性
+// */
+//@ConfigurationProperties(prefix = "dynamic")
+//public class DynamicDataSourceProperties {
+//    private Map<String, DataSourceProperties> datasource = new LinkedHashMap<>();
+//
+//    public Map<String, DataSourceProperties> getDatasource() {
+//        return datasource;
+//    }
+//
+//    public void setDatasource(Map<String, DataSourceProperties> datasource) {
+//        this.datasource = datasource;
+//    }
+//}

+ 193 - 0
src/main/java/com/sqx/modules/exportExecl/controller/ExportExeclController.java

@@ -0,0 +1,193 @@
+package com.sqx.modules.exportExecl.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jcraft.jsch.SftpException;
+import com.sqx.common.utils.PageUtils;
+import com.sqx.common.utils.Result;
+import com.sqx.common.utils.SftpUtil;
+import com.sqx.modules.common.service.CommonInfoService;
+import com.sqx.modules.exportExecl.mapper.ExportJobMapper;
+import com.sqx.modules.exportExecl.model.ExportJob;
+import com.sqx.modules.exportExecl.service.ExportJobService;
+import com.sqx.modules.order.dao.AppOrderDao;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.util.IOUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+
+@Slf4j
+@Api(tags={"管理端-导出"})
+@RestController
+@RequestMapping("/admin/export")
+@RequiredArgsConstructor
+public class ExportExeclController {
+
+    private final AppOrderDao appOrderDao;
+
+    private final ExportJobMapper exportJobMapper;
+
+    private final ExportJobService exportJobService;
+
+    private final CommonInfoService commonInfoService;
+
+    private final SftpUtil sftpUtil;
+
+    @GetMapping("excelOrder")
+    @ApiOperation("导出卡密列表")
+    public Result excelOrder(Integer status, String phone, Long shopId, String userName,
+                             String orderNumber, Integer orderType, String shopName, String riderPhone,
+                             String startTime, String endTime, String userId, String payStartTime, String payEndTime) throws Exception{
+        Integer size = appOrderDao.excelAllOrderAdminCount( status, phone, shopId, userName, orderNumber, orderType,
+                shopName, riderPhone,startTime,endTime,payStartTime,payEndTime);
+        //可导出最大数量
+        String count=commonInfoService.findOne(431).getValue();
+        if(size>Integer.parseInt(count)){
+            return Result.error("导出总数不能超过"+Integer.parseInt(count)+",请添加筛选条件");
+        }
+        if(!StringUtils.hasText(userId)){
+            return Result.error("用户id不能为空");
+        }
+        StringBuffer stringBuffer=new StringBuffer();
+        if(status!=null){stringBuffer.append("状态:"+getState(status)+";");}
+        if(phone!=null&&!phone.trim().equals("")){stringBuffer.append("手机号:"+phone+";");}
+//        if(shopId!=null){stringBuffer.append(":"+shopId+";");}
+        if(userName!=null&&!userName.trim().equals("")){stringBuffer.append("昵称:"+userName+";");}
+        if(orderNumber!=null&&!orderNumber.trim().equals("")){stringBuffer.append("订单号:"+orderNumber+";");}
+        if(orderType!=null){stringBuffer.append("订单类型:"+(orderType==1?"上门":"外卖")+";");}
+        if(shopName!=null&&!shopName.trim().equals("")){stringBuffer.append("商铺名称:"+shopName+";");}
+        if(riderPhone!=null&&!riderPhone.trim().equals("")){stringBuffer.append("骑手手机号:"+riderPhone+";");}
+        if(startTime!=null&&!startTime.trim().equals("")){stringBuffer.append("开始时间:"+startTime+";");}
+        if(endTime!=null&&!endTime.trim().equals("")){stringBuffer.append("结束时间:"+endTime+";");}
+        if(payStartTime!=null&&!payStartTime.trim().equals("")){stringBuffer.append("支付开始时间:"+payStartTime+";");}
+        if(payEndTime!=null&&!payEndTime.trim().equals("")){stringBuffer.append("支付结束时间:"+payEndTime+";");}
+
+        ExportJob exportJob =new ExportJob();
+        exportJob.setFlag(0);
+        exportJob.setFileType("order");
+        exportJob.setConditionDetail(stringBuffer.toString());
+        exportJob.setConditions(","+(status==null?"":status)+","+phone+","+(shopId==null?"":shopId)+","+userName+","+orderNumber+","
+                +(orderType==null?"":orderType)+","+shopName+","
+                +riderPhone+","+startTime+","+endTime+","+payStartTime+","+payEndTime);
+        LocalDateTime localDateTime = LocalDateTime.now();
+        String time=localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
+        exportJob.setFileName(time+"订单列表.xlsx");
+        exportJob.setUserId(userId);
+        exportJob.setCreateTime(new Date());
+        exportJob.setUpdateTime(new Date());
+        int a=exportJobMapper.insert(exportJob);
+        if (a==1){
+            return Result.success("新增导出计划成功");
+        }else{
+            return Result.error("新增导出计划失败");
+        }
+    }
+    @GetMapping("excelRecharge")
+    @ApiOperation("导出充值记录")
+    public Result excelRecharge(String rechargeOrder, String acount,String userId) throws Exception{
+        if(!StringUtils.hasText(userId)){
+            return Result.error("用户id不能为空");
+        }
+        StringBuffer stringBuffer=new StringBuffer();
+        if(rechargeOrder!=null&&rechargeOrder!=""){stringBuffer.append("充值订单号:"+rechargeOrder+";");}
+        if(acount!=null&&acount!=""){stringBuffer.append("被充值账号:"+acount+";");}
+
+        ExportJob exportJob =new ExportJob();
+        exportJob.setFlag(0);
+        exportJob.setFileType("recharge");
+        exportJob.setConditionDetail(stringBuffer.toString());
+        exportJob.setConditions(","+rechargeOrder+","+acount);
+        LocalDateTime localDateTime = LocalDateTime.now();
+        String time=localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
+        exportJob.setFileName(time+"充值记录.xlsx");
+        exportJob.setCreateTime(new Date());
+        exportJob.setUpdateTime(new Date());
+        exportJob.setUserId(userId);
+        int a=exportJobMapper.insert(exportJob);
+        if (a==1){
+            return Result.success("新增导出计划成功");
+        }else{
+            return Result.error("新增导出计划失败");
+        }
+    }
+    //    任意文件读取/下载
+    @ApiOperation(value = "查询下载列表")
+    @GetMapping("listByUser")
+    public Result List(String userId,String state,String startTime,String endTime,Integer curretPage,Integer pageSize) throws IOException {
+
+        QueryWrapper queryWrapper=new QueryWrapper<ExportJob>();
+
+        queryWrapper.eq("user_id",userId);
+        if(StringUtils.hasText(state)){
+            queryWrapper.eq("flag",state);
+        }
+        if(StringUtils.hasText(startTime)){
+            queryWrapper.ge("create_time",startTime);
+        }
+        if(StringUtils.hasText(endTime)){
+            queryWrapper.le("create_time",endTime);
+        }
+        queryWrapper.orderByDesc("create_time");
+        IPage<ExportJob> iPage=exportJobService.page(new Page<>(curretPage,pageSize),queryWrapper);
+        PageUtils pageUtils = new PageUtils(iPage);
+        return Result.success().put("data", pageUtils);
+    }
+
+    //    任意文件读取/下载
+    @ApiOperation(value = "文件下载")
+    @GetMapping("readBuffer")
+    public void readbuffer(String filename,HttpServletResponse response) throws IOException {
+        if(filename.contains("..") || filename.contains("/")){
+            throw new IOException("文件名异常");
+        }
+        String value=commonInfoService.findOne(430).getValue()==null?"":commonInfoService.findOne(430).getValue();
+        sftpUtil.login();
+        try {
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+            // 下载文件的默认名称
+            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));
+            sftpUtil.downloadStream(value,filename,response.getOutputStream());
+            log.info("文件下载成功");
+        }catch (IOException | SftpException e){
+            log.error(e.getMessage());
+            log.error("文件下载失败");
+        }finally {
+            if (sftpUtil.isConnected()){
+                sftpUtil.logout();
+            }
+        }
+    }
+
+    // '订单状态 0待结算 1待支付 2直接购买(未支付) 7商家待接单 8商家拒绝接单 6制作中  3待取餐/派送中 4已完成 5已取消 ',
+    private String getState(Integer state){
+        switch (state){
+            case 1: return "待支付";
+            case 2: return "未支付";
+            case 3: return "待取餐";
+            case 4: return "已完成";
+            case 5: return "已取消";
+            case 6: return "制作中";
+            case 7: return "商家待接单";
+            case 8: return "商家拒绝接单";
+            case 0: return "待结算";
+            default: return state+"";
+        }
+    }
+}

+ 0 - 136
src/main/java/com/sqx/modules/exportExecl/controller/exportExeclController.java

@@ -1,136 +0,0 @@
-package com.sqx.modules.exportExecl.controller;
-
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.sqx.common.utils.DateUtils;
-import com.sqx.common.utils.PageUtils;
-import com.sqx.common.utils.Result;
-import com.sqx.modules.exportExecl.mapper.ExportJobMapper;
-import com.sqx.modules.exportExecl.model.ExportJob;
-import com.sqx.modules.exportExecl.service.ExportJobService;
-import com.sqx.modules.order.dao.AppOrderDao;
-import com.sqx.modules.order.entity.TbOrder;
-import com.sqx.modules.order.service.AppOrderService;
-import com.sqx.modules.utils.excel.ExcelData;
-import com.sqx.modules.utils.excel.ExportExcelUtils;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.poi.util.IOUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.util.StringUtils;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.servlet.http.HttpServletResponse;
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Date;
-import java.util.List;
-
-@Slf4j
-@Api(tags={"管理端-导出"})
-@RestController
-@RequestMapping("/admin/export")
-public class exportExeclController {
-
-    @Autowired
-    private AppOrderDao appOrderDao;
-
-    @Autowired
-    private ExportJobMapper exportJobMapper;
-
-    @Autowired
-    private ExportJobService exportJobService;
-
-    @GetMapping("excelOrder")
-    @ApiOperation("导出卡密列表")
-    public Result excelOrder(Integer status, String phone, Long shopId, String userName,
-                             String orderNumber, Integer orderType, String shopName, String riderPhone,
-                             String startTime, String endTime, String userId,HttpServletResponse response) throws Exception{
-        Integer size = appOrderDao.excelAllOrderAdminCount( status, phone, shopId, userName, orderNumber, orderType,
-                shopName, riderPhone,startTime,endTime);
-        int i=10000;
-        if(size>i){
-            return Result.error("导出总数不能超过"+i+",请添加筛选条件");
-        }
-        StringBuffer stringBuffer=new StringBuffer();
-        if(status!=null){stringBuffer.append("状态:"+status+";");}
-        if(phone!=null&&phone!=""){stringBuffer.append("手机号:"+phone+";");}
-//        if(shopId!=null){stringBuffer.append(":"+shopId+";");}
-        if(userName!=null&&userName!=""){stringBuffer.append("昵称:"+userName+";");}
-        if(orderNumber!=null&&orderNumber!=""){stringBuffer.append("订单号:"+orderNumber+";");}
-        if(orderType!=null){stringBuffer.append("订单类型:"+orderType+";");}
-        if(shopName!=null&&shopName!=""){stringBuffer.append("商铺名称:"+shopName+";");}
-        if(riderPhone!=null&&riderPhone!=""){stringBuffer.append("骑手手机号:"+riderPhone+";");}
-        if(startTime!=null&&startTime!=""){stringBuffer.append("开始时间:"+startTime+";");}
-        if(endTime!=null&&endTime!=""){stringBuffer.append("结束时间:"+endTime+";");}
-
-        ExportJob exportJob =new ExportJob();
-        exportJob.setFlag(0);
-        exportJob.setFileType("order");
-        exportJob.setConditionDetail(stringBuffer.toString());
-        exportJob.setConditions(","+(status==null?"":status)+","+phone+","+(shopId==null?"":shopId)+","+userName+","+orderNumber+","
-                +(orderType==null?"":orderType)+","+shopName+","
-                +riderPhone+","+startTime+","+endTime);
-        LocalDateTime localDateTime = LocalDateTime.now();
-        String time=localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
-        exportJob.setFileName(time+"订单列表.xlsx");
-        exportJob.setUserId(userId);
-        int a=exportJobMapper.insert(exportJob);
-        if (a==1){
-            return Result.success("新增导出计划成功");
-        }else{
-            return Result.error("新增导出计划失败");
-        }
-    }
-    //    任意文件读取/下载
-    @ApiOperation(value = "查询下载列表")
-    @GetMapping("listByUser")
-    public Result List(String userId,String state,String startTime,String endTime,Integer curretPage,Integer pageSize) throws IOException {
-
-        QueryWrapper queryWrapper=new QueryWrapper<ExportJob>();
-
-        queryWrapper.eq("user_id",userId);
-        if(StringUtils.hasText(state)){
-            queryWrapper.eq("flag",state);
-        }
-        if(StringUtils.hasText(startTime)){
-            queryWrapper.ge("create_time",startTime);
-        }
-        if(StringUtils.hasText(endTime)){
-            queryWrapper.le("create_time",endTime);
-        }
-        IPage<ExportJob> iPage=exportJobService.page(new Page<>(curretPage,pageSize),queryWrapper);
-        PageUtils pageUtils = new PageUtils(iPage);
-        return Result.success().put("data", pageUtils);
-    }
-
-    //    任意文件读取/下载
-    @ApiOperation(value = "任意文件读取/下载")
-    @GetMapping("readBuffer")
-    public Result readbuffer(String filename,HttpServletResponse response) throws IOException {
-        if(filename.contains("..") || filename.contains("/")){
-            return Result.error("文件名异常");
-        }
-        try (InputStream inputStream = new BufferedInputStream(Files.newInputStream(Paths.get(filename)))){
-            response.setHeader("Content-Disposition", "attachment; filename=" + filename);
-            response.setContentLength((int) Files.size(Paths.get(filename)));
-            response.setContentType("application/octet-stream");
-
-            // 使用 Apache Commons IO 库的工具方法将输入流中的数据拷贝到输出流中
-            IOUtils.copy(inputStream, response.getOutputStream());
-            return Result.success("文件下载成功");
-        }catch (IOException e){
-            log.error(e.getMessage());
-            return Result.error("文件下载失败");
-        }
-    }
-}

+ 4 - 2
src/main/java/com/sqx/modules/exportExecl/model/ExportJob.java

@@ -6,6 +6,8 @@ import java.util.Date;
 import com.baomidou.mybatisplus.annotation.TableId;
 
 import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -41,11 +43,11 @@ public class ExportJob implements Serializable {
     private String userId;
 
     @ApiModelProperty(value = "创建时间")
-//    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
     private Date createTime;
 
     @ApiModelProperty(value = "更新时间")
-//    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
     private Date updateTime;
 
     @ApiModelProperty(value = "导出条件描述")

+ 8 - 8
src/main/java/com/sqx/modules/order/controller/OrderController.java

@@ -51,14 +51,14 @@ public class OrderController extends AbstractController {
         return appOrderService.selectAllOrderAdmin(page, limit, status, phone, shopId, userName, orderNumber, orderType, shopName, riderPhone, indentStatus, reservationFlag, startTime, endTime, payStartTime, payEndTime);
     }
 
-    @GetMapping("excelOrder")
-    @ApiOperation("导出卡密列表")
-    public void excelOrder(Integer status, String phone, Long shopId, String userName,
-                           String orderNumber, Integer orderType,String shopName,String riderPhone,
-                           String startTime, String endTime, HttpServletResponse response) throws Exception{
-        ExcelData excelData = appOrderService.excelAllOrderAdmin(status, phone, shopId, userName, orderNumber, orderType, shopName, riderPhone, startTime, endTime);
-        ExportExcelUtils.exportExcel(response,"订单列表.xlsx",excelData);
-    }
+//    @GetMapping("excelOrder")
+//    @ApiOperation("导出卡密列表")
+//    public void excelOrder(Integer status, String phone, Long shopId, String userName,
+//                           String orderNumber, Integer orderType,String shopName,String riderPhone,
+//                           String startTime, String endTime, HttpServletResponse response) throws Exception{
+//        ExcelData excelData = appOrderService.excelAllOrderAdmin(status, phone, shopId, userName, orderNumber, orderType, shopName, riderPhone, startTime, endTime);
+//        ExportExcelUtils.exportExcel(response,"订单列表.xlsx",excelData);
+//    }
 
     @ApiOperation("完成订单")
     @PostMapping(value = "accomplishOrder")

+ 6 - 5
src/main/java/com/sqx/modules/order/dao/AppOrderDao.java

@@ -3,6 +3,7 @@ package com.sqx.modules.order.dao;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.sqx.datasource.annotation.DataSource;
 import com.sqx.modules.order.entity.TbOrder;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
@@ -23,23 +24,23 @@ public interface AppOrderDao extends BaseMapper<TbOrder> {
     IPage<TbOrder> selectOrder(Page<TbOrder> pages,@Param("status") Integer status,@Param("phone") String phone, @Param("shopId") Long shopId,
                                @Param("userName") String userName, @Param("orderNumber") String orderNumber,@Param("orderType") Integer orderType,@Param("shopName")String shopName);
 
-
+    @DataSource("dynamic")
     IPage<TbOrder> selectAllOrderAdmin(Page<TbOrder> pages,@Param("status") Integer status,@Param("phone") String phone, @Param("shopId") Long shopId,
                                @Param("userName") String userName, @Param("orderNumber") String orderNumber,@Param("orderType") Integer orderType,
                                        @Param("shopName")String shopName,@Param("riderPhone") String riderPhone, @Param("indentStatus") String indentStatus, @Param("reservationFlag") String reservationFlag,
                                        @Param("startTime") String startTime,@Param("endTime") String endTime, @Param("payStartTime") String payStartTime, @Param("payEndTime") String payEndTime);
-
+    @DataSource("dynamic")
     List<TbOrder> excelAllOrderAdmin(@Param("status") Integer status,@Param("phone") String phone, @Param("shopId") Long shopId,
                                        @Param("userName") String userName, @Param("orderNumber") String orderNumber,
                                      @Param("orderType") Integer orderType,@Param("shopName")String shopName,
                                      @Param("riderPhone") String riderPhone,@Param("startTime") String startTime,
-                                     @Param("endTime") String endTime);
-
+                                     @Param("endTime") String endTime,@Param("payStartTime") String payStartTime,@Param("payEndTime") String payEndTime);
+    @DataSource("dynamic")
     Integer excelAllOrderAdminCount(@Param("status") Integer status,@Param("phone") String phone, @Param("shopId") Long shopId,
                                      @Param("userName") String userName, @Param("orderNumber") String orderNumber,
                                      @Param("orderType") Integer orderType,@Param("shopName")String shopName,
                                      @Param("riderPhone") String riderPhone,@Param("startTime") String startTime,
-                                     @Param("endTime") String endTime);
+                                     @Param("endTime") String endTime,@Param("payStartTime") String payStartTime,@Param("payEndTime") String payEndTime);
 
 
     IPage<TbOrder> selectOrderByAdmin(Page<TbOrder> pages,@Param("status") Integer status,@Param("phone") String phone,

+ 1 - 1
src/main/java/com/sqx/modules/order/service/AppOrderService.java

@@ -34,7 +34,7 @@ public interface AppOrderService extends IService<TbOrder> {
 
     ExcelData excelAllOrderAdmin(Integer status, String phone, Long shopId,
                                  String userName, String orderNumber, Integer orderType, String shopName,
-                                 String riderPhone, String startTime, String endTime);
+                                 String riderPhone, String startTime, String endTime,String payStartTime, String payEndTime);
 
     Result selectOrderByUserId(Long userId, String date, String dateType);
 

+ 3 - 2
src/main/java/com/sqx/modules/order/service/impl/AppAppOrderServiceImpl.java

@@ -1288,9 +1288,9 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
     @Override
     public ExcelData excelAllOrderAdmin(Integer status, String phone, Long shopId,
                                         String userName, String orderNumber, Integer orderType, String shopName,
-                                        String riderPhone, String startTime, String endTime) {
+                                        String riderPhone, String startTime, String endTime,String payStartTime, String payEndTime) {
         List<TbOrder> tbOrderIPage = appOrderDao.excelAllOrderAdmin( status, phone, shopId, userName, orderNumber, orderType,
-                shopName, riderPhone,startTime,endTime);
+                shopName, riderPhone,startTime,endTime,payStartTime,payEndTime);
 //        for (int i = 0; i < tbOrderIPage.size(); i++) {
 //            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>()
 //                    .eq("order_id", tbOrderIPage.get(i).getOrderId()));
@@ -1362,6 +1362,7 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
             row.add(order.getPayMoney());
 
             row.add(order.getErrandMoneyIsShop());
+            row.add(order.getRemark());
             row.add(order.getPayTime());
             //支付方式  1微信支付  2余额支付  3支付宝支付
             if(order.getPayType()!=null && order.getPayType()==1){

+ 5 - 29
src/main/java/com/sqx/modules/utils/excel/ExportExcelUtils.java

@@ -9,6 +9,7 @@ import org.apache.poi.xssf.usermodel.*;
 import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder;
 
 import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
@@ -208,30 +209,9 @@ public class ExportExcelUtils {
         return new int[] { r, g, b };
     }
 
-    public static void writeExcel2(File file,String fileName, ExcelData excelData) throws Exception {
+    public static void writeExcel2(ByteArrayOutputStream os,String fileName, ExcelData excelData) throws Exception {
         // 文件输出位置
-//        File file=new File(fileName);
-        OutputStream out = new FileOutputStream(file);
-//        ExcelWriter writer = EasyExcelFactory.getWriter(out);
-//
-//        // 动态添加表头,适用一些表头动态变化的场景
-//        Sheet sheet=new S
-//
-//        sheet1.setSheetName("第一个sheet");
-//
-//        // 创建一个表格,用于 Sheet 中使用
-//        Table table1 = new Table(1);
-//
-//        // 无注解的模式,动态添加表头
-//        table1.setHead(DataUtil.createTestListStringHead());
-//        // 写数据
-//        writer.write1(createDynamicModelList(), sheet1, table1);
-//
-//        // 将上下文中的最终 outputStream 写入到指定文件中
-//        writer.finish();
-//
-//        // 关闭流
-//        out.close();
+
         List<List<String>> headList=new ArrayList<>();
         List<String> list=excelData.getTitles();
         for (int i = 0; i < list.size(); i++) {
@@ -241,11 +221,8 @@ public class ExportExcelUtils {
         }
         ExcelWriter excelWriter =null;
         try {
-            //设置前端下载文件名
-//            fileName = new String(("床位导入模板").getBytes("utf-8"),"iso-8859-1");
-//            response.setCharacterEncoding("utf-8");
-            // 指定写用哪个class去写
-            excelWriter = EasyExcel.write(out).head(headList).build();
+
+            excelWriter = EasyExcel.write(os).head(headList).build();
             // 同一个sheet只要创建一次
             WriteSheet writeSheet = EasyExcel.writerSheet("sheet1").build();
             // 调用写入
@@ -257,7 +234,6 @@ public class ExportExcelUtils {
             if (excelWriter != null) {
                 excelWriter.finish();
             }
-            out.close();
         }
     }
 }

+ 115 - 20
src/main/java/com/sqx/scheduler/export/ExportScheduler.java

@@ -1,9 +1,14 @@
 package com.sqx.scheduler.export;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.sqx.modules.coupon.service.TbCouponUserService;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.sqx.common.utils.SftpUtil;
+import com.sqx.modules.app.entity.RechargeRecord;
+import com.sqx.modules.app.service.RechargeRecordService;
+import com.sqx.modules.common.service.CommonInfoService;
 import com.sqx.modules.exportExecl.mapper.ExportJobMapper;
 import com.sqx.modules.exportExecl.model.ExportJob;
+import com.sqx.modules.exportExecl.service.ExportJobService;
 import com.sqx.modules.order.service.AppOrderService;
 import com.sqx.modules.utils.excel.ExcelData;
 import com.sqx.modules.utils.excel.ExportExcelUtils;
@@ -13,14 +18,21 @@ import lombok.extern.slf4j.Slf4j;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.InputStream;
 import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
@@ -36,62 +48,100 @@ import java.util.concurrent.TimeUnit;
 @RequestMapping("/admin/aaaaaa")
 public class ExportScheduler {
 
-    private final TbCouponUserService tbCouponUserService;
+    private final CommonInfoService commonInfoService;
     private final RedissonClient redissonClient;
-    @Autowired
-    private ExportJobMapper exportJobMapper;
-    @Autowired
-    private AppOrderService appOrderService;
+    private final RedisTemplate redisTemplate;
+    private final ExportJobService exportJobService;
+    private final AppOrderService appOrderService;
+    private final RechargeRecordService rechargeRecordService;
+    private final SftpUtil sftpUtil;
+
 
     /**
      * 将所有超过失效时间的优惠券改为失效状态
      * 每分钟运行一次
      */
     @Async
-    @Scheduled(cron = "0 */1 * * * ?", zone = "Asia/Shanghai")
-    @GetMapping("excelOrder")
+    @Scheduled(cron = "18 */1 * * * ?", zone = "Asia/Shanghai")
+//    @GetMapping("excelOrder")
     public void orderExport() throws Exception {
-        List<ExportJob> exportJobList=exportJobMapper.selectList(new QueryWrapper<ExportJob>()
-                .eq("flag",0).last("limit 2"));
-        log.info("exportJobList==========="+exportJobList);
+        List<ExportJob> exportJobList=exportJobService.list(new QueryWrapper<ExportJob>()
+                .eq("flag",0).last("order by create_time limit 10"));
+        log.info("本次导出数据exportJobList==========="+exportJobList);
         if (null == exportJobList ||exportJobList.isEmpty()){
             return;
         }
+        int runningCount =exportJobService.count(new QueryWrapper<ExportJob>().eq("flag",-1));
+        if (runningCount>=4){
+            //同时执行的任务超过4条,不再新增任务
+            return;
+        }
         for(ExportJob exportJob:exportJobList){
             long bgTime = System.currentTimeMillis();
             String jobExecuteKey = SchedulerLock.EXPORT_LOCK + ":" + exportJob.getExportId();
+            String jobExecuteRedisKey = SchedulerLock.EXPORT_LOCK +":R:" + exportJob.getExportId();
             RLock lock = redissonClient.getLock(jobExecuteKey);
-            if (lock.tryLock(0, 30, TimeUnit.SECONDS)) {
+            if (lock.tryLock(0, 5, TimeUnit.SECONDS)) {
+                boolean isRedisKey = redisTemplate.hasKey(jobExecuteRedisKey);
+                //rediskey避免重复导出
+                if(isRedisKey){
+                    log.info(exportJob.getExportId()+"已执行,跳过");
+                    continue;
+                }
+                redisTemplate.opsForValue().set(jobExecuteRedisKey, "LOCK", 5, TimeUnit.MINUTES);
+                //设置为执行中
+                exportJob.setFlag(-1);
+                exportJob.setUpdateTime(new Date());
+                exportJobService.updateById(exportJob);
                 String fileName=exportJob.getFileName();
                 String fileType=exportJob.getFileType();
+                InputStream inputStream=null;
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
                 try {
                     ExcelData excelData=new ExcelData();
                     if("order".equals(fileType)){
                         excelData=getOrderExcelData(exportJob);
+                    }else if("recharge".equals(fileType)){
+                        excelData=getRechargeOrderExcelData(exportJob);
                     }
-                    File file=new File(fileName);
-                    ExportExcelUtils.writeExcel2(file,fileName,excelData);
-                    double fileSize = file.length();
+                    String value=commonInfoService.findOne(430).getValue();
+                    ExportExcelUtils.writeExcel2(os,fileName,excelData);
+                    byte[] buffer = os.toByteArray();
+                    inputStream = new ByteArrayInputStream(buffer);
+                    double fileSize = os.size();
                     double fileSizeKB = new BigDecimal(fileSize/1024).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); //转换单位为KB
                     exportJob.setFileSize(String.valueOf(fileSizeKB));
                     exportJob.setFlag(1);
-                    exportJobMapper.updateById(exportJob);
+                    exportJob.setUpdateTime(new Date());
+                    sftpUtil.login();
+                    sftpUtil.upload(value,fileName,inputStream);
+                    exportJobService.updateById(exportJob);
                 } catch (Exception e) {
+                    exportJob.setUpdateTime(new Date());
                     exportJob.setFlag(2);
-                    exportJobMapper.updateById(exportJob);
-                    log.error(e.getMessage());
+                    exportJobService.updateById(exportJob);
+                    log.error(e.toString());
                 } finally {
                     try {
                         if (lock.isLocked()) {
                             lock.unlock();
                         }
+                        if(os!=null){
+                            os.close();
+                        }
+                        if(inputStream!=null){
+                            inputStream.close();
+                        }
+                        if(sftpUtil.isConnected()){
+                            sftpUtil.logout();
+                        }
                     } catch (RuntimeException re) {
                         log.error("报表解锁失败");
                     }
                 }
             }
             long edTime = System.currentTimeMillis();
-            log.info("执行:通用数据导出定时任务......执行任务完成,执行时长:{} s", (edTime - bgTime) / 1000);
+            log.info("执行:通用数据导出定时任务"+exportJob.getExportId()+"......执行任务完成,执行时长:{} s", (edTime - bgTime) / 1000);
         }
     }
     //订单导出
@@ -117,8 +167,53 @@ public class ExportScheduler {
         String riderPhone=conditions[8];
         String startTime=conditions[9];
         String endTime=conditions[10];
-        ExcelData excelData = appOrderService.excelAllOrderAdmin(status, phone, shopId, userName, orderNumber, orderType, shopName, riderPhone, startTime, endTime);
+        String payStartTime=conditions[11];
+        String payEndTime=conditions[12];
+        ExcelData excelData = appOrderService.excelAllOrderAdmin(status, phone, shopId, userName, orderNumber, orderType, shopName, riderPhone, startTime, endTime,payStartTime,payEndTime);
 
         return excelData;
     }
+
+    //充值记录导出
+    private ExcelData getRechargeOrderExcelData(ExportJob exportJob){
+        String[] conditions=exportJob.getConditions().split(",",-1);
+        String rechargeOrder=conditions[1];
+        String acount=conditions[2];
+        QueryWrapper qw=new QueryWrapper<RechargeRecord>();
+        if(StringUtils.hasText(rechargeOrder)){
+            qw.eq("order_no",rechargeOrder);
+        }
+        if(StringUtils.hasText(acount)){
+            qw.eq("user_phone",acount);
+        }
+        ExcelData data = new ExcelData();
+        data.setName("订单列表");
+        List<String> titles = new ArrayList();
+        titles.add("用户id");titles.add("编号");titles.add("充值金额");titles.add("充值前余额");
+        titles.add("充值后余额"); titles.add("被充值账号(手机号)");titles.add("被充值名称");titles.add("被充值昵称");
+        titles.add("被充值头像"); titles.add("更新时间");titles.add("充值时间");titles.add("充值人账号");
+        titles.add("备注");
+        data.setTitles(titles);
+        List<RechargeRecord> recordList=rechargeRecordService.list(qw);
+        List<List<Object>> rows = new ArrayList();
+        for (RechargeRecord record:recordList){
+            List<Object> row = new ArrayList();
+            row.add(record.getUserId());
+            row.add(record.getOrderNo());
+            row.add(record.getAmount());
+            row.add(record.getOldMoney());
+            row.add(record.getBalance());
+            row.add(record.getUserPhone());
+            row.add(record.getUserName());
+            row.add(record.getUserNick());
+            row.add(record.getUserAvatar());
+            row.add(record.getUpdateTime());
+            row.add(record.getCreateTime());
+            row.add(record.getAccount());
+            row.add(record.getRemark());
+            rows.add(row);
+        }
+        data.setRows(rows);
+        return data;
+    }
 }

+ 41 - 0
src/main/resources/application-dev.yml

@@ -3,8 +3,10 @@ spring:
         type: com.alibaba.druid.pool.DruidDataSource
         druid:
             driver-class-name: com.mysql.cj.jdbc.Driver
+#            url: jdbc:mysql://172.16.20.104:3306/tcwm2.5?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true&serverTimezone=CTT
             url: jdbc:mysql://172.16.20.108:3306/tcwm2.5?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true&serverTimezone=CTT
             username: root
+#            password: ch@2025.wm
             password: chuanghai@2024
             initial-size: 15
             max-active: 100
@@ -108,3 +110,42 @@ secure-api:
 
 mp:
     temp: true
+sftp:
+    username: export
+    password: Waimai2024#
+    host: 172.16.20.108
+    port: 22
+
+dynamic:
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://172.16.20.104:3306/tcwm2.5?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true&serverTimezone=CTT
+#    url: jdbc:mysql://172.16.20.108:3306/tcwm2.5?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true&serverTimezone=CTT
+    username: root
+    password: ch@2025.wm
+#    password: chuanghai@2024
+    initial-size: 15
+    max-active: 100
+    min-idle: 10
+    max-wait: 60000
+    pool-prepared-statements: true
+    max-pool-prepared-statement-per-connection-size: 20
+    time-between-eviction-runs-millis: 60000
+    min-evictable-idle-time-millis: 300000
+    #Oracle需要打开注释
+    #validation-query: SELECT 1 FROM DUAL
+    test-while-idle: true
+    test-on-borrow: false
+    test-on-return: false
+    stat-view-servlet:
+        enabled: true
+        url-pattern: /druid/*
+        #login-username: admin
+        #login-password: admin
+    filter:
+        stat:
+            log-slow-sql: true
+            slow-sql-millis: 1000
+            merge-sql: false
+        wall:
+            config:
+                multi-statement-allow: true

+ 39 - 0
src/main/resources/application-prod.yml

@@ -109,3 +109,42 @@ secure-api:
 
 mp:
     temp: false
+sftp:
+    username: export
+    password: Waimai2024#
+    host: 172.16.20.105
+    port: 22
+#查询备用数据库
+dynamic:
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://172.16.20.104:3306/tcwm2.5?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true&serverTimezone=CTT
+    #    url: jdbc:mysql://172.16.20.108:3306/tcwm2.5?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true&serverTimezone=CTT
+    username: root
+    password: ch@2025.wm
+    #    password: chuanghai@2024
+    initial-size: 15
+    max-active: 100
+    min-idle: 10
+    max-wait: 60000
+    pool-prepared-statements: true
+    max-pool-prepared-statement-per-connection-size: 20
+    time-between-eviction-runs-millis: 60000
+    min-evictable-idle-time-millis: 300000
+    #Oracle需要打开注释
+    #validation-query: SELECT 1 FROM DUAL
+    test-while-idle: true
+    test-on-borrow: false
+    test-on-return: false
+    stat-view-servlet:
+        enabled: true
+        url-pattern: /druid/*
+        #login-username: admin
+        #login-password: admin
+    filter:
+        stat:
+            log-slow-sql: true
+            slow-sql-millis: 1000
+            merge-sql: false
+        wall:
+            config:
+                multi-statement-allow: true

+ 12 - 0
src/main/resources/mapper/order/OrderMapper.xml

@@ -194,6 +194,12 @@
         <if test="endTime!=null and endTime!='' ">
             and date_format(tor.create_time,'%Y-%m-%d') &lt;= date_format(#{endTime},'%Y-%m-%d')
         </if>
+        <if test="payStartTime != null and payStartTime != ''">
+            and date_format(tor.pay_time,'%Y-%m-%d') >= date_format(#{payStartTime},'%Y-%m-%d')
+        </if>
+        <if test="payEndTime != null and payEndTime != '' ">
+            and date_format(tor.pay_time,'%Y-%m-%d') &lt;= date_format(#{payEndTime},'%Y-%m-%d')
+        </if>
         order by tor.pay_time desc, tor.create_time desc
     </select>
 
@@ -237,6 +243,12 @@
         <if test="endTime!=null and endTime!='' ">
             and date_format(tor.create_time,'%Y-%m-%d') &lt;= date_format(#{endTime},'%Y-%m-%d')
         </if>
+        <if test="payStartTime != null and payStartTime != ''">
+            and date_format(tor.pay_time,'%Y-%m-%d') >= date_format(#{payStartTime},'%Y-%m-%d')
+        </if>
+        <if test="payEndTime != null and payEndTime != '' ">
+            and date_format(tor.pay_time,'%Y-%m-%d') &lt;= date_format(#{payEndTime},'%Y-%m-%d')
+        </if>
         order by tor.pay_time desc, tor.create_time desc
     </select>