TradeBiz.java 7.77 KB
package com.cjs.site.biz.info;

import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import com.cjs.site.biz.pub.CommonBiz;
import com.cjs.site.dao.info.TradeDao;
import com.cjs.site.dao.user.quota.OtcHolderDao;
import com.cjs.site.model.info.TradeInfo;
import com.cjs.site.util.ehcache.EhCacheUtil;
import com.cjs.site.util.lang.DateEnum;
import com.cjs.site.util.lang.DateUtil;
import com.cjs.site.util.lang.JsonUtil;
import com.cjs.site.util.t2.T2Result;
import com.cjs.site.util.t2.T2Util;

/**
 * 交易
 * 
 * @author tongyufu
 *
 */
@Service
public class TradeBiz {

    Logger                      log              = LogManager.getLogger();
    private static final String CK_EXCHANGE_INFO = "ck_exchange_info";
    @Autowired
    private TradeDao            tradeDao;
    @Autowired
    private CommonBiz           commonBiz;
    @Autowired
    private OtcHolderDao        otcHolderDao;

    /**
     * 非交易权益过户
     * 
     * @param otcCode 藏品编号
     * @param sellFundAccount 出让方会员号
     * @param buyFundAccount 认购方会员号
     * @param occurAmount 过户数量
     * @param remark 备注
     * @return
     */
    public T2Result transfer(String otcCode, String sellFundAccount, String buyFundAccount,
                             Integer occurAmount, String remark) {
        Assert.state(StringUtils.isNotBlank(otcCode), "藏品编号不能为空");
        Assert.state(StringUtils.isNotBlank(sellFundAccount), "出让方会员号不能为空");
        Assert.state(StringUtils.isNotBlank(buyFundAccount), "认购方会员号不能为空");
        String sellSdcAccount = otcHolderDao.queryOtcAccount(sellFundAccount);
        String buySdcAccount = otcHolderDao.queryOtcAccount(buyFundAccount);
        Assert.notNull(sellSdcAccount, "出让方权益账号不存在");
        Assert.notNull(buySdcAccount, "认购方权益账号不存在");
        Map<String, Object> params = new HashMap<String, Object>();

        params.put("op_branch_no", "11"); //操作分支机构
        params.put("operator_no", "2001"); //操作员
        params.put("user_type", "1");
        params.put("op_password", "");
        params.put("op_station", "cms"); //站点地址
        params.put("op_entrust_way", "7"); //申请方式(7:网络)
        params.put("menu_id", "220202");
        params.put("function_id", "601004");
        params.put("branch_no", "11"); //分支机构
        params.put("audit_action", "0");
        params.put("sdc_code", otcCode);
        params.put("sdc_account", sellSdcAccount);
        params.put("opp_sdcaccount", buySdcAccount);
        params.put("gh_type", "0"); //过户类别(0:流通股)
        params.put("occur_amount", occurAmount);
        params.put("remark", remark);
        params.put("sdcexch_type", "");
        T2Result result = T2Util.request(params, "601004");
        log.info("非交易权益过户:" + result);
        return result;
    }

    /**
     * 获取交易行情(AJAX轮询)
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> exchaneInfo() {
        Map<String, Object> trade = (Map<String, Object>) EhCacheUtil.get(CK_EXCHANGE_INFO);

        if (trade != null) {
            return trade;
        }

        try {
            int marketStatus = commonBiz.checkMarketStatus();

            trade = new HashMap<String, Object>();
            trade.put("code", "0");
            trade.put("datetime", DateUtil.getNow());
            trade.put("data", null);

            // 1:初始化;
            if (marketStatus == 1) {
                EhCacheUtil.put(CK_EXCHANGE_INFO, trade, 60, 60);
                return trade;
            }

            // 3:闭市;
            if (marketStatus == 3) {
                // 15:00:00闭市,行情获取延长5分钟
                int nowTime = Integer.parseInt(DateUtil.getNow(DateEnum.UNSIGNED_TIME));
                int endTime = 150500;
                if (nowTime < endTime) {
                    marketStatus = 2;
                } else {
                    List<TradeInfo> trades = tradeDao.queryList();
                    if (!trades.isEmpty()) {
                        TradeInfo tradeInfo = trades.get(0);
                        List<Map<String, Object>> tradeMap = JsonUtil.fromJson(tradeInfo.getTrade(),
                            List.class);
                        this.sort(tradeMap);
                        trade.put("data", tradeMap);
                        trade.put("datetime", DateUtil.getNow());
                        //trade.put("datetime", DateUtil.parseDate(tradeInfo.getLastDate(), DateEnum.DATETIME));
                    }
                    EhCacheUtil.put(CK_EXCHANGE_INFO, trade, 60, 60);
                    return trade;
                }
            }

            // 2:连续竞价;
            if (marketStatus == 2) {
                T2Result result = requestTradeData();
                trade = new HashMap<String, Object>();
                trade.put("code", result.getCode());
                trade.put("datetime", DateUtil.getNow());
                if (result.getCode() == 0) {
                    trade.put("data", this.processData(result.getData()));
                }
                EhCacheUtil.put(CK_EXCHANGE_INFO, trade, 5, 5);
            }
        } catch (Exception e) {
            log.error("", e);
        }
        return trade;
    }

    /**
     * 发送消息到WebSocket客户端
     */
    public void sendToClient(String message,
                             List<WebSocketSession> websocketSessions) throws IOException {
        if (StringUtils.isNotBlank(message) && websocketSessions != null) {
            for (WebSocketSession session : websocketSessions) {
                try {
                    if (session.isOpen()) {
                        session.sendMessage(new TextMessage(message));
                    } else {
                        websocketSessions.remove(session);
                    }
                } catch (Exception e) {
                    log.error("WebScoket传输出错[" + session.getId() + "]:" + e.getMessage());
                    websocketSessions.remove(session);
                }
            }
        }
    }

    /** 从恒生获取行情 */
    private T2Result requestTradeData() {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("mchexch_type", "O1");
        params.put("mch_code", ""); // 交易撮合代码
        params.put("check_str", "0");
        return T2Util.request(params, "649015");
    }

    private List<Map<String, Object>> processData(List<Map<String, Object>> data) {
        if (data.isEmpty()) {
            return data;
        }
        tradeDao.deleteAll();
        TradeInfo tradeInfo = new TradeInfo();
        String trade = JsonUtil.toJson(data);
        tradeInfo.setTrade(trade);
        tradeDao.save(tradeInfo);

        this.sort(data);
        return data;
    }

    // 藏品代码排序
    private void sort(List<Map<String, Object>> list) {
        Collections.sort(list, new Comparator<Map<String, Object>>() {

            @Override
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                Integer code1 = Integer.parseInt(o1.get("mch_code").toString());
                Integer code2 = Integer.parseInt(o2.get("mch_code").toString());
                return code1.compareTo(code2);
            }

        });
    }

}