BatchEntrustTask.java 7.15 KB
package com.cjs.cms.biz.trade;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cjs.cms.biz.pub.CommonBiz;
import com.cjs.cms.dao.pub.OtcExchangeDateDao;
import com.cjs.cms.dao.trade.HisOtcEntrustDao;
import com.cjs.cms.dao.trade.OtcEntrustBatchDao;
import com.cjs.cms.model.trade.OtcEntrustBatchInfo;
import com.cjs.cms.util.lang.DateEnum;
import com.cjs.cms.util.lang.DateUtil;
import com.cjs.cms.util.lang.PageUtils;
import com.cjs.cms.util.lang.SpringContextUtil;
import com.cjs.cms.util.redis.JedisTemplate;

/**
 * 自动委托挂单
 * 
 * @author tongyufu
 *
 */
@Service
public class BatchEntrustTask {

    final Logger               log = LogManager.getLogger(BatchEntrustTask.class);
    @Autowired
    private CommonBiz          commonBiz;
    @Autowired
    private HisOtcEntrustDao   hisOtcEntrustDao;
    @Autowired
    private JedisTemplate      jedisTemplate;
    @Autowired
    private OtcEntrustBatchDao otcEntrustBatchDao;
    @Autowired
    private OtcExchangeDateDao otcExchangeDateDao;

    public void entrust() {
        String entrustTask = "entrust:task:" + DateUtil.getNow(DateEnum.UNSIGNED_DATE);
        log.info("批量委托开始:" + DateUtil.getNow());
        if (jedisTemplate.get(entrustTask) != null) {
            log.info("批量委托终止:当天任务已执行");
            return;
        }
        jedisTemplate.set(entrustTask, "1", 60 * 60 * 24);
        if (!commonBiz.checkTradeDay()) {
            log.info("批量委托终止:非交易日");
            return;
        }
        /**/
        int checkTime = 0;
        while (commonBiz.checkMarketStatus() != 2) {
            try {
                log.info("批量委托重试:当前非可交易状态");
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            checkTime += 10;
            if (checkTime >= 600) {
                log.info("批量委托终止:非可交易状态");
                return;
            }
        }

        Integer lastTradeDate = hisOtcEntrustDao.queryLastEntrustDate();
        if (lastTradeDate == null) {
            log.info("批量委托终止:最后交易日期为空");
            return;
        }

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("date", lastTradeDate);
        int entrustTotal = hisOtcEntrustDao.queryEntrustTotal(params);
        int fetchCount = new BigDecimal(entrustTotal / 200.0).setScale(0, RoundingMode.CEILING)
            .intValue();
        if (entrustTotal == 0) {
            log.info("批量委托终止:委托列表为空");
            return;
        }

        ExecutorService exec = Executors.newFixedThreadPool(10);
        final BatchEntrustBiz batchEntrustBiz = SpringContextUtil.getBean(BatchEntrustBiz.class);
        batchEntrustBiz.setEntrustNo(new AtomicInteger(0));
        final CountDownLatch latch = new CountDownLatch(entrustTotal);
        try {
            for (int i = 0; i < fetchCount; i++) {
                params.put("rows", 200);
                params.put("page", i + 1);
                PageUtils.processOralcePage(params);
                List<OtcEntrustBatchInfo> entrusts = hisOtcEntrustDao.queryEntrust(params);
                Map<String, String> currDateMap = this.getCurrentDate(entrusts);
                for (int j = 0; j < entrusts.size(); j++) {
                    final OtcEntrustBatchInfo entrust = entrusts.get(j);
                    entrust.setCurrDate(DateUtil.getNow(DateEnum.UNSIGNED_DATE));
                    entrust.setCurrTime(DateUtil.getNow(DateEnum.UNSIGNED_TIME2));
                    //if (!this.compareCurrDate(currDateMap.get(entrust.getOpStation()), entrust.getCurrDate())) {
                    if (currDateMap.get(entrust.getOpStation()) != null) {
                        entrust.setSuccess("0");
                        entrust.setT2Result("委托已连续超过7天");
                        otcEntrustBatchDao.save(entrust);
                        continue;
                    }
                    exec.submit(new Runnable() {
                        @Override
                        public void run() {
                            batchEntrustBiz.entrust(entrust, latch);
                        }
                    });
                }
            }
            latch.await(10, TimeUnit.MINUTES);
        } catch (Exception e) {
            log.error("批量委托出错", e);
        } finally {
            exec.shutdown();
        }
        log.info("批量委托结束:" + DateUtil.getNow());
        this.backups();
    }

    @SuppressWarnings("unused")
    private boolean compareCurrDate(String startDate, String endDate) {
        if (StringUtils.isBlank(startDate)) {
            return true;
        }
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        start.setTime(DateUtil.parseDate(startDate, DateEnum.UNSIGNED_DATE));
        end.setTime(DateUtil.parseDate(endDate, DateEnum.UNSIGNED_DATE));
        start.add(Calendar.DAY_OF_MONTH, 7);
        return start.after(end);
    }

    private Map<String, String> getCurrentDate(List<OtcEntrustBatchInfo> entrusts) {
        List<String> opStations = new ArrayList<String>();
        Map<String, String> currDateMap = new HashMap<String, String>();
        for (OtcEntrustBatchInfo entrust : entrusts) {
            String station = entrust.getOpStation();
            if (StringUtils.isNotBlank(station) && station.length() > 20) {
                opStations.add(station);
            }
        }
        if (opStations.isEmpty()) {
            return currDateMap;
        }
        //当天前第七个交易日
        Integer sevenDay = otcExchangeDateDao.queryBeforeDay(7);
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("opStations", opStations);
        params.put("initDate", sevenDay);
        List<Map<String, Object>> currDates = otcEntrustBatchDao.queryCurrDate(params);
        for (Map<String, Object> currDate : currDates) {
            currDateMap.put(currDate.get("OP_STATION").toString(),
                currDate.get("CURR_DATE").toString());
        }
        return currDateMap;
    }

    /**
     * 批量委托结束后,将之前的委托记录转移到历史表中。
     * 为了防止当天多次执行或者委托有效期变更,备份10个交易日前的数据
     */
    private void backups() {
        Integer workDay = otcExchangeDateDao.queryBeforeDay(10);
        log.info("批量委托备份数据:" + workDay);
        otcEntrustBatchDao.backupsEntrust(workDay);
        otcEntrustBatchDao.deleteToBackups(workDay);
    }
}