生成对账文件_实现

 

我方每天在服务器上生成对账文件, 第三方来取.

 

1.需求:

 

 

 

2.思路

生成对账文件的程序是一个定时任务: 凌晨2点运行此程序
1.设置好 对账文件存放的路径(工程部门给外部平台一个地址,他们自己过来取)
2.在这个路径下新建一个文件 .  格式是.txt
3. 连接数据库,查询支付表(可能多表查询), 查询前一天的数据. 按照接口文档需要的字段  查询到对应字段 ,并拼接
4.把查出来的数据(eg:101486120190325083431|20190325|10.00|0|1|0042930413|SWShopMall),  放到  .txt文件里

 

 
 
 
3.代码
package com.seaway.open.open_bank_luoyang_check;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.yaml.snakeyaml.Yaml;

import com.seaway.open.open_bank_luoyang_check.configure.Configure;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.cli.Argument;
import io.vertx.core.cli.CLI;
import io.vertx.core.cli.TypedOption;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.jdbc.JDBCClient;
import io.vertx.ext.jdbc.spi.impl.HikariCPDataSourceProvider;
import io.vertx.ext.sql.ResultSet;
import io.vertx.ext.sql.SQLConnection;

public class Runner extends AbstractVerticle {
    private static final Logger logger = LogManager.getLogger(Runner.class);
    private Configure gconfigure = null;
    private JDBCClient jdbcClient = null;

    // Vertx vertx = Vertx.vertx();
    public Configure getGconfigure() {
        return gconfigure;
    }

    public void setGconfigure(Configure gconfigure) {
        this.gconfigure = gconfigure;
    }

    public synchronized JDBCClient getJdbcClientInstance() {

        if (jdbcClient == null) {
            try {
                HikariCPDataSourceProvider HikariCPDataSource = new HikariCPDataSourceProvider();

                JsonObject jdbcobject = JsonObject.mapFrom(getGconfigure().getJdbcConfig());

                jdbcobject.put("autoCommit", true);

                jdbcClient = JDBCClient.create(vertx, HikariCPDataSource.getDataSource(jdbcobject));
                logger.info("初始化数据库连接池成功 {}", jdbcobject.toString());

            } catch (SQLException e) {
                logger.error("连接数据库失败:{}", e);
            }
        }
        return jdbcClient;
    }

    public static void main(String[] args) {
        Runner runner = new Runner();
        Vertx vertx = Vertx.vertx();
        runner.start(vertx);

    }

    private void initConfigure() {
        CLI cli = CLI.create("open_bank_luoyang_check").setSummary("开放平台xx银行对账文件生成程序")
                .addOption(new TypedOption<Boolean>().setType(Boolean.class).setLongName("configure")
                        .setShortName("cfg").setDescription("指定配置文件").setFlag(true).setRequired(true))
                .addArgument(new Argument().setDescription("文件绝对路径(yaml格式)").setArgName("filename").setRequired(true));

        StringBuilder builder = new StringBuilder();
        cli.usage(builder);

        String ConfigureFile = null;
        // int liFile = this.context.processArgs().indexOf("-cfg");
        // if (liFile == -1) {
        //
        // logger.error("指定配置文件: [-cfg <filename>]");
        // logger.error(builder);
        // stop();
        // }
        // try {
        // ConfigureFile = this.context.processArgs().get(liFile + 1);
        // if (!new File(ConfigureFile).exists()) {
        //
        // logger.error("配置文件[" + ConfigureFile + "]不存在");
        // logger.error(builder);
        // stop();
        // }
        // } catch (Exception e) {
        //
        // logger.error("指定配置文件: [-cfg <filename>]",e);
        // logger.error(builder);
        // stop();
        //
        // }
        Yaml yaml = new Yaml();
        ConfigureFile = "F:/Users/Administrator/git/open6/open_bank_check/open_bank_luoyang_check/src/main/resources/open_bank_luoyang_check.yaml";
        try {
            InputStream in = new FileInputStream(new File(ConfigureFile));
            setGconfigure(yaml.loadAs(in, Configure.class));
            logger.info("读取配置文件[" + ConfigureFile + "]:[" + getGconfigure() + "]");
        } catch (Exception e) {
            logger.error("解析文件错误", e);
            stop();
        }

    }

    @Override
    public void stop() {
        logger.info("关闭系统!");
        vertx.close();

        System.exit(0);
    }

    // @Override
    public void start(Vertx vertx) {

        initConfigure();

        HikariCPDataSourceProvider HikariCPDataSource = new HikariCPDataSourceProvider();
        try {
            JsonObject jdbcobject = JsonObject.mapFrom(getGconfigure().getJdbcConfig());

            jdbcobject.put("autoCommit", true);

            jdbcClient = JDBCClient.create(vertx, HikariCPDataSource.getDataSource(jdbcobject));
            logger.info("初始化数据库连接池成功 {}", jdbcobject.toString());

        } catch (SQLException e) {
            logger.error("连接数据库失败:", e);
        }

        /**
         * 功能描述: 当天对前一天生活圈发生的支付或退款交易进行校对和清算 对账文件的文件名:SWShopMall_yyyyMMdd.txt 文件内容格式: 订单号
         * |交易日期|金额|交易状态|交易类型|客户号 |商户号 20160602 |20190218|9.01| 0 | 1 | 037894566
         * |SWShopMall 文件格式是.txt 文件中不能出现空格,空行 每天早上7点之前必须将前一天的对账文件放置服务器上,否则将影响对账交易 交易状态
         * 0:成功1:失败 交易类型 1:付款2:退款;
         */

        // 每晚2点生成
        vertx.setTimer(getGconfigure().getFileConfigure().getTaskTime(), id1 -> {
            executeTask();
            vertx.setPeriodic(getGconfigure().getFileConfigure().getCycleTaskTime(), id2 -> {
                executeTask();
            });
            vertx.cancelTimer(id1);
        });

    }

    private void executeTask() {
        logger.info("定时任务开始");
        String dateTime = LocalDateTime.now().minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        // 如果dateTime日期20190324时间小于设置的时间,则取配置时间
        if (!getGconfigure().getCheckConfigure().getCheckDate().equals("00000000"))
            dateTime = getGconfigure().getCheckConfigure().getCheckDate();

        String checkPath = getGconfigure().getCheckConfigure().getCheckPath();
        String filePath = checkPath + "/SWShopMall_" + dateTime + ".txt";
        logger.info("filePath: {}", filePath);
        File file = new File(filePath);
        if (file.exists()) {
            logger.info("文件已经生成 退出");
            return;
        } else {
            logger.info("文件不存在 新建文件");
            try {
                file.createNewFile();
                logger.info("创建成功");

                if (jdbcClient == null) {
                    logger.info("jdbcClient is null getJdbcClientInstance");
                    jdbcClient = getJdbcClientInstance();
                } else {
                    logger.info("jdbcClient not null");
                }
                String times = dateTime;
                jdbcClient.getConnection(jdbcConnect -> {
                    if (jdbcConnect.failed()) {
                        logger.error("连接出错: {}", jdbcConnect.cause().getMessage());
                        return;
                    } else {
                        final SQLConnection connection = jdbcConnect.result();
                        logger.info("取得连接");
                        // 查询数据库
                        String beginTime = times + "000000";
                        String endTime = times + "235959";
                        // 金额保留两位小数,多余舍掉 cast(trunc(pay_amount/10000,2) AS NUMBER (10, 2))
                        // 金额保留两位小数,四舍五入 to_char(pa.pay_amount/10000,'fm99,999,990.00')
                        // 该sql金额会至少保留两位小数(单位元)
                        String querySql = "\n\nselect pay_id || '|' || substr(pay_time, 0, 8) || '|'  || \n"
                                + "case  \n" + "  when substr(to_char(pay_amount/10000,'fm99,999,990.0000'),-2) > 00\n"
                                + "  then\n" + "       to_char(pay_amount/10000,'fm99,999,990.0000')\n" + "  else\n"
                                + "       to_char(pay_amount/10000,'fm99,999,990.00')\n" + "  end \n" + "  || '|' ||\n"
                                + "case  when stats in(3,5,9) then\n" + "          0\n" + "         else\n"
                                + "          1\n" + "       end || '|' || 1 || '|' || user_id || '|' || '"
                                + getGconfigure().getFileConfigure().getMerchantCode() + "'\n"
                                + "from payment_item where pay_time between '" + beginTime + "' and '" + endTime
                                + "'  and  gateway_id = '" + getGconfigure().getFileConfigure().getGateway_id()
                                + "'  and channel_id = '" + getGconfigure().getFileConfigure().getChannel_id() + "' \n"
                                + "union all\n" + "select r.refund_id || '|' || substr(r.refund_time, 0, 8)|| '|' || \n"
                                + "case  \n"
                                + "  when substr(to_char(r.refund_amount/10000,'fm99,999,990.0000'),-2) > 00\n"
                                + "  then\n" + "       to_char(r.refund_amount/10000,'fm99,999,990.0000')\n"
                                + "  else\n" + "       to_char(r.refund_amount/10000,'fm99,999,990.00')\n" + "  end \n"
                                + "|| '|' ||\n" + "case r.stats \n" + "         when 1 then\n" + "          0\n"
                                + "         when 2 then\n" + "          1\n" + "         else\n" + "          1\n"
                                + "       end || '|' || 2 || '|' || p.user_id || '|' || '"
                                + getGconfigure().getFileConfigure().getMerchantCode() + "'\n"
                                + "from refund_item r,payment_item p   \n"
                                + "where r.pay_id = p.pay_id and r.refund_time between '" + beginTime + "' and '"
                                + endTime + "'  and  r.gateway_id = '"
                                + getGconfigure().getFileConfigure().getGateway_id() + "'  and r.channel_id = '"
                                + getGconfigure().getFileConfigure().getChannel_id() + "'\n";
                        logger.info("querySql: {}", querySql);
                        connection.query(querySql, queryresult -> {
                            if (queryresult.succeeded()) {
                                connection.close();
                                logger.info("queryresult succeeded");
                                ResultSet queryResultSet = queryresult.result();
                                List<JsonArray> jsonArraysList = queryResultSet.getResults();
                                // logger.info("jsonArraysList: {}", jsonArraysList);
                                FileOutputStream outSTr = null;
                                BufferedOutputStream buff = null;
                                try {
                                    outSTr = new FileOutputStream(file);
                                } catch (FileNotFoundException e1) {
                                    logger.error(e1);
                                }
                                buff = new BufferedOutputStream(outSTr);
                                logger.info("size: " + jsonArraysList.size());
                                for (int i = 0; i < jsonArraysList.size(); i++) {
                                    /*** 把数据写入到磁盘 */
                                    try {
                                        buff.write((jsonArraysList.get(i).getString(0) + "\n").getBytes());
                                        // 每多少次清理一次 缓冲区
                                        if (i % getGconfigure().getFileConfigure().getFlushCount() == 0
                                                && buff != null) {
                                            buff.flush();
                                            logger.info("flush: " + i);
                                        }
                                    } catch (IOException e) {
                                        logger.error("写入磁盘出错", e);

                                    }
                                }

                                if (buff != null) {
                                    try {
                                        buff.flush();
                                        buff.close();
                                    } catch (IOException e) {
                                        logger.error("关闭出错", e);
                                    }
                                }
                                logger.info("{}日对账文件写入磁盘成功,共{}条", times, jsonArraysList.size());
                            } else {
                                connection.close();
                                logger.error("执行查询错误,关闭连接: {}", queryresult.cause().getMessage());
                            }
                        });
                    }
                });
            } catch (IOException e) {
                logger.error("程序异常: ", e);
            }
        }
    }
}

 

 

控制台运行此程序,对账文件生成

.........................

......................

 

 

 去这个路径下看看,发现对账文件已经生成了

 

有bug--回头看发现程序里面需要一个回车符

 

 

 

 

4.补充

这个程序重点:

1.要熟悉java基础.(建文件 /往文件写数据)

2.sql函数的运用.

公司数据库用的是oracle数据库.  下面是把生成对账文件内容的sql 从程序里摘出来.大家可以学习下

select pay_id || '|' || substr(pay_time, 0, 8) || '|'  || 
case  
  when substr(to_char(pay_amount/10000,'fm99,999,990.0000'),-2) > 00
  then
       to_char(pay_amount/10000,'fm99,999,990.0000')
  else
       to_char(pay_amount/10000,'fm99,999,990.00')
  end 
  || '|' ||
case  when stats in(3,5,9) then
          0
         else
          1
       end || '|' || 1 || '|' || user_id || '|' || 'SWShopMall'
from payment_item where pay_time between '20190326000000' and '20190326235959'  and  gateway_id = '10'  and channel_id = '1' 
union all
select r.refund_id || '|' || substr(r.refund_time, 0, 8)|| '|' || 
case  
  when substr(to_char(r.refund_amount/10000,'fm99,999,990.0000'),-2) > 00
  then
       to_char(r.refund_amount/10000,'fm99,999,990.0000')
  else
       to_char(r.refund_amount/10000,'fm99,999,990.00')
  end 
|| '|' ||
case r.stats 
         when 1 then
          0
         when 2 then
          1
         else
          1
       end || '|' || 2 || '|' || p.user_id || '|' || 'SWShopMall'
from refund_item r,payment_item p   
where r.pay_id = p.pay_id and r.refund_time between '20190326000000' and '20190326235959'  and  r.gateway_id = '10'  and r.channel_id = '1'

在数据库运行该sql, 这个就是对账文件里面放的内容. 已经用sql拼接好了.

 

 

  多加思考,多加训练.

 

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~补充二~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

上面的sql太长了, 是怎么要达到我想要的内容呢

1.先查出接口文档中字段(对账文件需要的字段).

标准的文件内容格式:
20160602|20190218|9.01|0|1|037894566|SWShopMal

 

 

2.然后再根据需求 改.  加函数/  加判断

eg:时间格式 /   金额显示格式(保留几位小数) /  只显示渠道的支付记录/   等等

 

转载于:https://www.cnblogs.com/PinkPink/p/10607853.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 开源的仓储对账快递的Java实现是一种基于开源技术的快递仓储对账系统的编写和开发过程。在Java语言中,我们可以使用诸如Spring、Hibernate等开源框架和库来实现这个系统。 首先,我们可以使用Spring框架来构建该系统的基本框架和结构。Spring提供了依赖注入、AOP、ORM等功能,使得系统的开发更加简单和高效。我们可以使用Spring MVC来构建系统的前后端交互接口,使用Spring Boot来实现系统的自动化配置和部署。 其次,对于仓储对账功能的实现,我们可以使用Hibernate框架来实现数据库的操作和管理。Hibernate是一个优秀的对象关系映射工具,它可以将Java对象和关系数据库中的数据进行映射,并提供了强大的查询和持久化功能。我们可以使用Hibernate来创建对账单对象和仓储物品对象的映射,以及实现对这些对象的增删改查操作。 此外,为了提高系统的安全性和性能,我们还可以使用其他开源工具和技术。例如,我们可以使用Spring Security框架来实现系统的权限管理和用户认证功能;使用Swagger来生成系统的API文档;使用Log4j来记录系统的运行日志;使用缓存技术如Redis来提高系统的性能等等。 总结来说,开源的仓储对账快递的Java实现基于开源技术和框架,可以快速、灵活地开发出功能强大、高效稳定的系统。通过使用Spring、Hibernate等工具,我们可以实现系统的结构、业务逻辑和持久化操作,并通过其他开源工具来增强系统的安全性和性能。这些开源技术在Java技术领域中得到了广泛应用和成熟的生态系统支持,为仓储对账快递的Java实现提供了可靠的基础。 ### 回答2: 开源的仓储对账快递Java实现是一种使用Java语言编写的开源软件,它用于仓储和快递行业的对账业务。下面我将从几个方面介绍其实现。 首先,它通过Java语言实现了快递和仓储业务的核心功能,例如管理订单、入库、出库等。它使用了Java的面向对象编程特性,通过定义类、接口和继承等方式进行了模块化设计。这样,我们可以更好地组织和管理代码,提高代码的可维护性和重用性。 其次,它采用了Java的网络编程技术,使得仓储和快递系统可以与其他系统进行通信。例如,它可以与物流系统对接,实现物流跟踪和状态更新。同时,它还可以与订单系统对接,实现订单数据的同步和更新。通过使用Java的网络编程技术,可以方便地实现与其他系统的交互。 第三,它使用了Java数据库技术,对仓储和快递的相关数据进行存储和管理。例如,它可以使用Java的JDBC库连接数据库,进行数据的增删改查操作。通过使用数据库技术,可以更好地管理和操作仓储和快递的数据,提高系统的性能和可扩展性。 另外,它还可以使用Java的日志库对系统的运行情况进行记录和跟踪。这样,在系统出现问题时,我们可以通过查看日志文件来定位问题的所在,提高系统的可靠性和稳定性。 总之,开源的仓储对账快递Java实现通过使用Java语言的特性和相关技术,实现了仓储和快递业务的核心功能,并能与其他系统进行通信和数据交互。它的开源特性还使得开发者可以根据自己的需求对其进行修改和扩展。 ### 回答3: 开源的仓储对账快递java实现,即通过使用Java编程语言,实现一个开源的仓储对账系统,用于快递行业的物流仓储管理和对账,以下是该系统的主要特点和功能: 1. 仓储管理:系统可以记录快递公司的仓储信息,包括仓库的位置、容量、存储量等相关信息。通过该系统,用户可以方便地管理仓库信息,并进行查找、筛选等操作。 2. 对账功能:系统可以实现对快递公司和仓储供应商之间的对账,包括入库、出库、运输等环节的对账,确保账目准确无误。通过系统的对账功能,可以有效地避免因账目错误导致的纠纷和损失。 3. 数据统计与分析:系统可以提供丰富的数据统计与分析功能,用户可以通过系统生成报表和图表,对仓储物流的各项指标进行分析和评估,以优化仓储管理和物流运营。 4. 库存管理:系统可以实时跟踪仓库中的存货情况,根据实际情况自动计算库存量,当库存不足时,系统会提醒用户及时补货,以保证供应链的畅通。 5. 安全管理:系统具备完善的权限控制和数据加密功能,保障用户的数据安全和隐私。 6. 可定制性:该系统采用Java开发,具有良好的可扩展性和可定制性,用户可以根据自身需求对系统进行二次开发和定制,以满足不同的业务需求。 综上所述,开源的仓储对账快递Java实现是一款功能强大、安全可靠的仓储管理系统,可以有效提升快递行业的物流效率和管理水平。使用该系统,用户可以更加方便地进行仓储管理、对账和数据分析,提高运营效益和客户满意度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值