package com.huiju.estateagents.redpack.service.impl;

import com.alibaba.excel.EasyExcel;
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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huiju.estateagents.base.ResponseBean;
import com.huiju.estateagents.center.taUser.entity.TaUser;
import com.huiju.estateagents.center.taUser.mapper.TaUserMapper;
import com.huiju.estateagents.common.CommConstant;
import com.huiju.estateagents.common.CommonUtils;
import com.huiju.estateagents.common.wxpay.WXPay;
import com.huiju.estateagents.common.wxpay.WXPayConstants;
import com.huiju.estateagents.common.wxpay.WxConfig;
import com.huiju.estateagents.entity.TaWxPayConfig;
import com.huiju.estateagents.excel.redPacket.AccountConsumeRecordExport;
import com.huiju.estateagents.excel.redPacket.AccountPayRecordExport;
import com.huiju.estateagents.excel.redPacket.AccountRefundRecordExport;
import com.huiju.estateagents.mapper.TaWxPayConfigMapper;
import com.huiju.estateagents.redpack.entity.*;
import com.huiju.estateagents.redpack.mapper.*;
import com.huiju.estateagents.redpack.service.ITaOrgOrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 组织订单表  服务实现类
 * </p>
 *
 * @author fxf
 * @since 2020-06-03
 */
@Slf4j
@Service
public class TaOrgOrderServiceImpl extends ServiceImpl<TaOrgOrderMapper, TaOrgOrder> implements ITaOrgOrderService {

    @Value("${pay-notify}")
    private String payNotify;

    @Autowired
    private TaOrgAccountMapper taOrgAccountMapper;

    @Autowired
    private TaOrgOrderMapper taOrgOrderMapper;

    @Autowired
    private TaOrgOrderDetailMapper taOrgOrderDetailMapper;

    @Autowired
    private TaOrgAccountDetailedListMapper taOrgAccountDetailedListMapper;

    @Autowired
    private TaOrgRefundApplicationMapper taOrgRefundApplicationMapper;

    @Autowired
    private TaOrgAccountBlockedMapper taOrgAccountBlockedMapper;

    @Autowired
    private TaOrgAccountCertificateMapper taOrgAccountCertificateMapper;

    @Autowired
    private TaUserMapper taUserMapper;

    @Autowired
    private TaWxPayConfigMapper taWxPayConfigMapper;

    @Override
    public IPage<TaOrgOrder> listByCondition(IPage<TaOrgOrder> pg, String orderType, Integer orgId, String tradeNo, Integer isOffline, String tradingStatus, String receivePhone, String itemType, LocalDate startDate, LocalDate endDate) {
        IPage<TaOrgOrder> result = null;

        if (CommConstant.ITEM_TYPE_RECHARGE.equals(orderType) || CommConstant.ITEM_TYPE_REFUND.equals(orderType)) {
            result = taOrgOrderMapper.orderListByRechargeOrRefund(pg, orderType, orgId, tradeNo, isOffline, tradingStatus, startDate, endDate);
            return result;
        } else if (CommConstant.ITEM_TYPE_REDPACKAGE.equals(orderType)) {
            result = taOrgOrderMapper.orderListByConsume(pg, orderType, orgId, tradeNo, tradingStatus, receivePhone, itemType, startDate, endDate);
            return result;
        } else {
            return null;
        }
    }

    /**
     * 微信支付
     *
     * @param taOrgOrder
     * @param clientIp
     * @return
     */
    @Override
    public ResponseBean payUnifiedOrder(TaOrgOrder taOrgOrder, String clientIp) throws Exception {
        taOrgOrder = taOrgOrderMapper.selectById(taOrgOrder.getOrderId());
        //构建微信配置
        WxConfig config = getWxConfig(0);
        WXPay wxpay = new WXPay(config);

        //获取支付的钱数并且判断是自动锁房还是手动锁房,自动锁房需要锁定房源，手动锁房跳过
        String payPrice = String.valueOf(taOrgOrder.getAmount());

        //生成商户订单
//        String tradeNo = CommonUtils.generateTradeNo("CJ");
//        taOrgOrder.setTradeNo(tradeNo);

        //下单
        Map<String, String> data = new HashMap<String, String>();
        data.put("body", "微信支付");
        //商品号唯一
        data.put("out_trade_no", taOrgOrder.getTradeNo());
        data.put("device_info", "");
        data.put("fee_type", "CNY");
        //金额 后台计算
        data.put("total_fee", payPrice);
        //终端IP
        data.put("spbill_create_ip", clientIp);
        //回调地址
        data.put("notify_url", payNotify + CommConstant.ITEM_TYPE_RECHARGE);
        // 此处指定为APP支付
        data.put("trade_type", "NATIVE");
        Map<String, String> resp = wxpay.unifiedOrder(data);
        log.info("下单成功：{}", resp);
        if (resp.get("result_code").equalsIgnoreCase(WXPayConstants.FAIL)) {
            throw new Exception(resp.get("err_code_des"));
        }

        return ResponseBean.success(resp.get("code_url"));
    }

    @Override
    public ResponseBean saveCzOrder(Double amount, Integer orgId, Integer userId, String ip) throws Exception {
        ResponseBean responseBean = new ResponseBean();

        // 获取下单人名称
        TaUser taUser = taUserMapper.selectById(userId);
        if (taUser == null) {
            responseBean.addError("fail");
            return responseBean;
        }

        // 1.创建订单主表信息
        TaOrgOrder taOrgOrder = new TaOrgOrder();
        taOrgOrder.setOrgId(orgId);
        taOrgOrder.setTradeNo(CommonUtils.generateTradeNo(CommConstant.RECHARGE));
        taOrgOrder.setAmount(CommonUtils.yuanToFen(amount));
        taOrgOrder.setCreateDate(LocalDateTime.now());
        taOrgOrder.setStatus(CommConstant.STATUS_NORMAL);
        taOrgOrder.setTradingStatus(CommConstant.TRADING_STATUS_PROCESSING);
        taOrgOrder.setIsOffline(false);
        taOrgOrder.setUserId(userId);
        taOrgOrder.setUserName(taUser.getUserName());
        if (taOrgOrderMapper.insert(taOrgOrder) < 1) {
            responseBean.addError("fail");
            return responseBean;
        }

        // 2.创建订单详情表信息
        TaOrgOrderDetail taOrgOrderDetail = new TaOrgOrderDetail();
        taOrgOrderDetail.setOrderId(taOrgOrder.getOrderId());
        taOrgOrderDetail.setOrgId(orgId);
        taOrgOrderDetail.setItemType(CommConstant.ITEM_TYPE_RECHARGE);
        taOrgOrderDetail.setAmount(CommonUtils.yuanToFen(amount));
        taOrgOrderDetail.setUnitPrice(CommonUtils.yuanToFen(amount));
        taOrgOrderDetail.setQuantity(1);
        taOrgOrderDetail.setStatus(CommConstant.STATUS_NORMAL);
        if (taOrgOrderDetailMapper.insert(taOrgOrderDetail) < 1) {
            taOrgOrderMapper.deleteById(taOrgOrder.getOrderId());
            responseBean.addError("fail");
            return responseBean;
        }

        // 3.请求微信接口获取支付二维码
        return payUnifiedOrder(taOrgOrder, ip);
    }

    @Override
    public ResponseBean saveRefundOrder(Double amount, Integer orgId, Integer userId) {
        ResponseBean responseBean = new ResponseBean();

        // 获取下单人名称
        TaUser taUser = taUserMapper.selectById(userId);
        if (taUser == null) {
            responseBean.addError("fail");
            return responseBean;
        }

        // 1.创建订单主表信息
        TaOrgOrder taOrgOrder = new TaOrgOrder();
        taOrgOrder.setOrgId(orgId);
        taOrgOrder.setTradeNo(CommonUtils.generateTradeNo(CommConstant.REFUND));
        taOrgOrder.setAmount(CommonUtils.yuanToFen(amount));
        taOrgOrder.setCreateDate(LocalDateTime.now());
        taOrgOrder.setStatus(CommConstant.STATUS_NORMAL);
        taOrgOrder.setTradingStatus(CommConstant.TRADING_STATUS_PROCESSING);
        taOrgOrder.setIsOffline(false);
        taOrgOrder.setUserId(userId);
        taOrgOrder.setUserName(taUser.getUserName());
        if (taOrgOrderMapper.insert(taOrgOrder) < 1) {
            responseBean.addError("fail");
            return responseBean;
        }

        // 2.创建订单详情表信息
        TaOrgOrderDetail taOrgOrderDetail = new TaOrgOrderDetail();
        taOrgOrderDetail.setOrderId(taOrgOrder.getOrderId());
        taOrgOrderDetail.setOrgId(orgId);
        taOrgOrderDetail.setItemType(CommConstant.ITEM_TYPE_REFUND);
        taOrgOrderDetail.setAmount(CommonUtils.yuanToFen(amount));
        taOrgOrderDetail.setUnitPrice(CommonUtils.yuanToFen(amount));
        taOrgOrderDetail.setQuantity(1);
        taOrgOrderDetail.setStatus(CommConstant.STATUS_NORMAL);
        if (taOrgOrderDetailMapper.insert(taOrgOrderDetail) < 1) {
            taOrgOrderMapper.deleteById(taOrgOrder.getOrderId());
            responseBean.addError("fail");
            return responseBean;
        }

        // 3.创建账户退款申请表信息
        TaOrgRefundApplication taOrgRefundApplication = new TaOrgRefundApplication();
        taOrgRefundApplication.setOrgId(orgId);
        taOrgRefundApplication.setUserId(userId);
        taOrgRefundApplication.setUserName(taUser.getUserName());
        taOrgRefundApplication.setAmount(CommonUtils.yuanToFen(amount));
        taOrgRefundApplication.setAuditStatus(CommConstant.CHECK_STATUS_CHECKING);
        taOrgRefundApplication.setOrderId(taOrgOrder.getOrderId());
        taOrgRefundApplication.setStatus(CommConstant.STATUS_NORMAL);
        taOrgRefundApplication.setCreateDate(LocalDateTime.now());
        taOrgRefundApplication.setReason("线上申请退款");
        if (taOrgRefundApplicationMapper.insert(taOrgRefundApplication) < 1) {
            taOrgOrderMapper.deleteById(taOrgOrder.getOrderId());
            taOrgOrderDetailMapper.deleteById(taOrgOrderDetail.getSerialNo());
            responseBean.addError("fail");
            return responseBean;
        }

        responseBean.addSuccess("success");
        return responseBean;
    }

    @Override
    public ResponseBean listCzOrderByCondition(Integer pageNum, Integer pageSize, LocalDate payStartTime, LocalDate payEndTime,
                                               String orderId, String tradeNo, String wxOrderId, Boolean isOffline, String tradingStatus, Integer orgId) {
        ResponseBean responseBean = new ResponseBean();
        IPage<TaOrgOrder> pg = new Page<>(pageNum, pageSize);
        pg = taOrgOrderMapper.listCzOrderByCondition(pg, payStartTime, payEndTime, orderId, tradeNo, wxOrderId, isOffline, tradingStatus, orgId);
        if (CollectionUtils.isNotEmpty(pg.getRecords())) {
            pg.getRecords().stream().forEach(r -> {
                QueryWrapper<TaOrgAccountCertificate> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("order_id", r.getOrderId());
                queryWrapper.eq("org_id", orgId);
                r.setCertificateList(taOrgAccountCertificateMapper.selectList(queryWrapper));
            });
        }
        responseBean.addSuccess(pg);
        return responseBean;
    }

    @Override
    public void exportCzOrderByCondition(LocalDate payStartTime, LocalDate payEndTime, String orderId, String tradeNo,
                                         String wxOrderId, Boolean isOffline, String tradingStatus, Integer orgId, HttpServletResponse response) throws Exception {
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("utf-8");
        List<AccountPayRecordExport> records = taOrgOrderMapper.exportCzOrderByCondition(payStartTime, payEndTime, orderId, tradeNo, wxOrderId, isOffline, tradingStatus, orgId);
        String fileName = URLEncoder.encode("充值订单", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), AccountPayRecordExport.class).sheet("充值订单").doWrite(records);
    }

    @Override
    public ResponseBean listRefundOrderByCondition(Integer pageNum, Integer pageSize, LocalDate refundStartTime, LocalDate refundEndTime, String orderId, String auditStatus, Integer orgId) {
        ResponseBean responseBean = new ResponseBean();
        IPage<TaOrgOrder> pg = new Page<>(pageNum, pageSize);
        pg = taOrgOrderMapper.listRefundOrderByCondition(pg, refundStartTime, refundEndTime, orderId, auditStatus, orgId);

        if (CollectionUtils.isNotEmpty(pg.getRecords())) {
            pg.getRecords().stream().forEach(r -> {
                QueryWrapper<TaOrgAccountCertificate> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("order_id", r.getOrderId());
                queryWrapper.eq("org_id", orgId);
                r.setCertificateList(taOrgAccountCertificateMapper.selectList(queryWrapper));
            });
        }
        responseBean.addSuccess(pg);
        return responseBean;
    }

    @Override
    public void exportRefundOrderByCondition(LocalDate refundStartTime, LocalDate refundEndTime, String orderId, String auditStatus, Integer orgId, HttpServletResponse response) throws Exception {
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("utf-8");
        List<AccountRefundRecordExport> records = taOrgOrderMapper.exportRefundOrderByCondition(refundStartTime, refundEndTime, orderId, auditStatus, orgId);
        String fileName = URLEncoder.encode("退款订单", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), AccountRefundRecordExport.class).sheet("退款订单").doWrite(records);
    }

    @Override
    public ResponseBean listRedPacketRecords(Integer pageNum, Integer pageSize, String phone, String activityId, String orderId, String wxOrderId, String tradeNo, Integer status, Integer orgId) {
        ResponseBean responseBean = new ResponseBean();
        IPage<TaOrgOrder> pg = new Page<>(pageNum, pageSize);
        responseBean.addSuccess(taOrgOrderMapper.listRedPacketRecords(pg, phone, activityId, orderId, wxOrderId, tradeNo, status, orgId));
        return responseBean;
    }

    @Override
    public ResponseBean listConsumeOrderByCondition(Integer pageNum, Integer pageSize, LocalDate startTime, LocalDate endTime, String orderId, Integer status, String consumeType, String phone, Integer orgId) {
        ResponseBean responseBean = new ResponseBean();
        IPage<TaOrgOrder> pg = new Page<>(pageNum, pageSize);
        responseBean.addSuccess(taOrgOrderMapper.listConsumeOrderByCondition(pg, startTime, endTime, orderId, status, consumeType, phone, orgId));
        return responseBean;
    }

    @Override
    public void exportConsumeOrderByCondition(LocalDate startTime, LocalDate endTime, String orderId, Integer status, String consumeType, String phone, Integer orgId, HttpServletResponse response) throws Exception {
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("utf-8");
        List<AccountConsumeRecordExport> records = taOrgOrderMapper.exportConsumeOrderByCondition(startTime, endTime, orderId, status, consumeType, phone, orgId);
        String fileName = URLEncoder.encode("消费订单", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), AccountConsumeRecordExport.class).sheet("消费订单").doWrite(records);
    }

    /**
     * 获取每个小程序独立的微信账户
     *
     * @param orgId
     * @return
     */
    private WxConfig getWxConfig(Integer orgId) throws Exception {
        //根据orgId获取支付配置
        QueryWrapper<TaWxPayConfig> taWxPayConfigQueryWrapper = new QueryWrapper<>();
        taWxPayConfigQueryWrapper.eq("org_id", orgId);
        TaWxPayConfig taWxPayConfig = taWxPayConfigMapper.selectOne(taWxPayConfigQueryWrapper);
        if (null == taWxPayConfig) {
            throw new Exception("请先完善支付信息");
        }
        log.info("正在配置orgId为{}的微信支付参数，商户号为{}", orgId, taWxPayConfig.getMchId());
        //把库里的值赋值给微信
        URL urlConet = new URL(taWxPayConfig.getApiPath());
        HttpURLConnection con = (HttpURLConnection) urlConet.openConnection();
        con.setRequestMethod("GET");
        con.setConnectTimeout(4 * 1000);
        InputStream inStream = con.getInputStream();
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[2048];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        inStream.close();

        WxConfig config = new WxConfig();
        config.setAppid(taWxPayConfig.getAppid());
        config.setMachId(taWxPayConfig.getMchId());
        config.setCertData(outStream.toByteArray());
        config.setKey(taWxPayConfig.getMchKey());
        return config;
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class})
    public ResponseBean refundOrder(String id, TaOrgRefundApplication refundApplication, Integer userId) {
        ResponseBean responseBean = new ResponseBean();

        //订单退款申请，更新账户的实际余额
        TaOrgAccount taOrgAccount = assembleRefundAccount(refundApplication.getOrgId(), refundApplication, CommConstant.ITEM_TYPE_REFUND);
        taOrgAccountMapper.updateById(taOrgAccount);

        //新增订单记录
        TaOrgOrder taOrgOrder = assembleTaOrgOrder(refundApplication.getOrgId(), taOrgAccount.getRechargeAmount(), userId);
        int taOrgOrderInsertResult = taOrgOrderMapper.insert(taOrgOrder);

        //新增关联订单明细
        TaOrgOrderDetail taOrgOrderDetail = assembleTaOrgOrderDetail(taOrgOrder.getOrderId(), refundApplication.getOrgId(), taOrgAccount.getRechargeAmount());
        int taOrgOrderDetailInsertResult = taOrgOrderDetailMapper.insert(taOrgOrderDetail);

        //新建账户消费流水
        TaOrgAccountDetailedList taOrgAccountDetailedList = assembleAccountDetailList(refundApplication, userId);
        int taOrgAccountDetailedListInsertResult = taOrgAccountDetailedListMapper.insert(taOrgAccountDetailedList);

        //更新账户退款申请
        TaOrgRefundApplication updateRefundApplication = assembleRefundApplication(userId, CommConstant.ITEM_TYPE_REJECT, refundApplication);
        QueryWrapper<TaOrgRefundApplication> taOrgRefundApplicationQueryWrapper = new QueryWrapper<>();
        taOrgRefundApplicationQueryWrapper.eq("org_id", refundApplication.getOrgId());
        int taOrgRefundApplicationUpdateResult = taOrgRefundApplicationMapper.update(updateRefundApplication, taOrgRefundApplicationQueryWrapper);

        //更新账户冻结记录
        int taOrgAccountBlockedUpdateResult = updateOrgAccountBlock(refundApplication);

        //插入凭证记录
        if (CollectionUtils.isNotEmpty(refundApplication.getCertificateList())) {
            List<TaOrgAccountCertificate> taOrgAccountCertificateList = assembleAccountCertificate(refundApplication.getOrgId(), taOrgAccount, taOrgAccountDetailedList.getSerialNo(), taOrgOrder.getOrderId(), userId, CommConstant.ITEM_TYPE_REFUND);
            taOrgAccountCertificateList.forEach(e -> {
                taOrgAccountCertificateMapper.insert(e);
            });
        }

        if (taOrgOrderInsertResult < 1 ||
                taOrgOrderDetailInsertResult < 1 ||
                taOrgAccountDetailedListInsertResult < 1 ||
                taOrgRefundApplicationUpdateResult < 1 ||
                taOrgAccountBlockedUpdateResult < 1) {
            responseBean.addError("订单退款失败");
            return responseBean;
        }

        return responseBean;
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class})
    public ResponseBean rejectOrder(String id, TaOrgRefundApplication refundApplication, Integer userId) {
        ResponseBean responseBean = new ResponseBean();

        //退款订单驳回，更新账户的可用余额
        TaOrgAccount taOrgAccount = assembleRefundAccount(refundApplication.getOrgId(), refundApplication, CommConstant.ITEM_TYPE_REJECT);
        taOrgAccountMapper.updateById(taOrgAccount);

        //更新账户冻结记录
        int taOrgAccountBlockedUpdateResult = updateOrgAccountBlock(refundApplication);

        //更新退款申请记录
        TaOrgRefundApplication updateRefundApplication = assembleRefundApplication(userId, CommConstant.ITEM_TYPE_REJECT, refundApplication);
        QueryWrapper<TaOrgRefundApplication> taOrgRefundApplicationQueryWrapper = new QueryWrapper<>();
        taOrgRefundApplicationQueryWrapper.eq("org_id", refundApplication.getOrgId());
        int taOrgRefundApplicationUpdateResult = taOrgRefundApplicationMapper.update(updateRefundApplication, taOrgRefundApplicationQueryWrapper);

        if (taOrgAccountBlockedUpdateResult < 1 ||
                taOrgRefundApplicationUpdateResult < 1) {
            responseBean.addError("驳回失败");
            return responseBean;
        }

        return responseBean;

    }

    /**
     * 构造充值账户
     *
     * @param orgId
     * @param refundApplication
     * @return
     */
    private TaOrgAccount assembleRefundAccount(Integer orgId, TaOrgRefundApplication refundApplication, String operateType) {
        TaOrgAccount selectOneAccount = selectTaOrgAccountById(orgId);

        TaOrgAccount rechargeAccount = new TaOrgAccount();
        rechargeAccount.setAccountId(selectOneAccount.getAccountId());

        if (CommConstant.ITEM_TYPE_REFUND.equals(operateType)) {
            rechargeAccount.setRealBalance(selectOneAccount.getRealBalance() - refundApplication.getAmount());
            rechargeAccount.setTotalRefund(selectOneAccount.getTotalRefund() + refundApplication.getAmount());
        }

        if (CommConstant.ITEM_TYPE_REJECT.equals(operateType)) {
            rechargeAccount.setAvailableBalance(refundApplication.getAmount());
        }

        rechargeAccount.setModifyDate(LocalDateTime.now());

        return rechargeAccount;
    }

    /**
     * 构造订单
     *
     * @param orgId
     * @param amount
     * @param userId
     * @return
     */
    private TaOrgOrder assembleTaOrgOrder(Integer orgId, Integer amount, Integer userId) {

        TaUser taUser = selectUserById(userId);
        TaOrgOrder taOrgOrder = new TaOrgOrder();
        taOrgOrder.setOrgId(orgId);
        taOrgOrder.setTradeNo(CommonUtils.generateTradeNo(CommConstant.RECHARGE));
        taOrgOrder.setAmount(amount);
        taOrgOrder.setCreateDate(LocalDateTime.now());
        taOrgOrder.setExpiryDate(LocalDateTime.now());
        taOrgOrder.setRemark("线下订单退费");
        taOrgOrder.setTradingStatus(String.valueOf(CommConstant.STATUS_NORMAL));
        taOrgOrder.setIsOffline(true);
        taOrgOrder.setUserId(userId);
        taOrgOrder.setUserName(taUser.getUserName());

        return taOrgOrder;
    }

    /**
     * 构造交订单详情信息
     *
     * @param orderId
     * @param orgId
     * @param amount
     * @return
     */
    private TaOrgOrderDetail assembleTaOrgOrderDetail(String orderId, Integer orgId, Integer amount) {
        TaOrgOrderDetail taOrgOrderDetail = new TaOrgOrderDetail();

        taOrgOrderDetail.setOrderId(orderId);
        taOrgOrderDetail.setOrgId(orgId);
        taOrgOrderDetail.setItemType(CommConstant.ITEM_TYPE_REFUND);
        taOrgOrderDetail.setAmount(amount);

        return taOrgOrderDetail;
    }

    /**
     * 构造消费流水记录
     *
     * @param refundApplication
     * @param userId
     * @return
     */
    private TaOrgAccountDetailedList assembleAccountDetailList(TaOrgRefundApplication refundApplication, Integer userId) {

        TaUser taUser = selectUserById(userId);
        TaOrgAccount taOrgAccount = selectTaOrgAccountById(refundApplication.getOrgId());

        TaOrgAccountDetailedList taOrgAccountDetailed = new TaOrgAccountDetailedList();
        taOrgAccountDetailed.setAccountId(taOrgAccount.getAccountId());
        taOrgAccountDetailed.setOrgId(refundApplication.getOrgId());
        taOrgAccountDetailed.setAmount(refundApplication.getAmount());
        //1收入,-1支出
        taOrgAccountDetailed.setSignType(CommConstant.STATUS_DELETE);
        taOrgAccountDetailed.setRemark("线下订单退费");
        taOrgAccountDetailed.setOrderId(refundApplication.getOrderId());
        taOrgAccountDetailed.setUserId(userId);
        taOrgAccountDetailed.setUserName(taUser.getUserName());

        return taOrgAccountDetailed;
    }

    /**
     * 构造交易凭证信息
     *
     * @param orgId
     * @param taOrgAccount
     * @param accountSerialNo
     * @param orderId
     * @param userId
     * @return
     */
    public List<TaOrgAccountCertificate> assembleAccountCertificate(Integer orgId, TaOrgAccount taOrgAccount, Integer accountSerialNo, String orderId, Integer userId, String consumeType) {
        TaUser taUser = selectUserById(userId);
        List<TaOrgAccountCertificate> taOrgAccountCertificateList = new ArrayList<>();

        taOrgAccount.getCertificateList().forEach(e -> {
            TaOrgAccountCertificate taOrgAccountCertificate = new TaOrgAccountCertificate();
            taOrgAccountCertificate.setOrgId(orgId);
            taOrgAccountCertificate.setAccountId(taOrgAccount.getAccountId());
            taOrgAccountCertificate.setAccountSerialNo(accountSerialNo);
            taOrgAccountCertificate.setOrderId(orderId);
            taOrgAccountCertificate.setConsumptionType(CommConstant.ITEM_TYPE_RECHARGE.equals(consumeType) ? CommConstant.ITEM_TYPE_RECHARGE : CommConstant.ITEM_TYPE_REFUND);
            taOrgAccountCertificate.setRemark(CommConstant.ITEM_TYPE_RECHARGE.equals(consumeType) ? "线下缴费" : "线下退费");
            taOrgAccountCertificate.setUrl(e);
            taOrgAccountCertificate.setCreateDate(LocalDateTime.now());
            taOrgAccountCertificate.setUserId(userId);
            taOrgAccountCertificate.setUserName(taUser.getUserName());
            taOrgAccountCertificateList.add(taOrgAccountCertificate);
        });

        return taOrgAccountCertificateList;
    }

    /**
     * 构造订单退款申请
     *
     * @param userId
     * @return
     */
    private TaOrgRefundApplication assembleRefundApplication(Integer userId, String operateType, TaOrgRefundApplication refundApplication) {
        TaUser taUser = selectUserById(userId);
        TaOrgRefundApplication taOrgRefundApplication = new TaOrgRefundApplication();
        taOrgRefundApplication.setAuditorId(userId);
        taOrgRefundApplication.setAuditorName(taUser.getUserName());
        taOrgRefundApplication.setAuditResult(CommConstant.ITEM_TYPE_REFUND.equals(operateType) ? "退款成功" : refundApplication.getAuditResult());
        taOrgRefundApplication.setAuditStatus(CommConstant.ITEM_TYPE_REFUND.equals(operateType) ? "agree" : "unAgree");

        return taOrgRefundApplication;
    }

    private Integer updateOrgAccountBlock(TaOrgRefundApplication refundApplication) {
        //更新账户冻结记录
        TaOrgAccountBlocked taOrgAccountBlocked = new TaOrgAccountBlocked();
        taOrgAccountBlocked.setStatus(CommConstant.STATUS_UNACCALIMED);
        QueryWrapper<TaOrgAccountBlocked> taOrgAccountBlockedQueryWrapper = new QueryWrapper<>();
        taOrgAccountBlockedQueryWrapper.eq("org_id", refundApplication.getOrgId());
        return taOrgAccountBlockedMapper.update(taOrgAccountBlocked, taOrgAccountBlockedQueryWrapper);
    }

    public TaOrgAccount selectTaOrgAccountById(Integer orgId) {
        QueryWrapper<TaOrgAccount> selectOneQuery = new QueryWrapper<>();
        selectOneQuery.eq("org_id", orgId);
        TaOrgAccount selectOneAccount = taOrgAccountMapper.selectOne(selectOneQuery);
        return selectOneAccount;
    }

    /**
     * 获取操作人
     *
     * @param userId
     * @return
     */
    public TaUser selectUserById(Integer userId) {
        //获取操作人
        QueryWrapper<TaUser> taUserQueryWrapper = new QueryWrapper<>();
        taUserQueryWrapper.eq("user_id", userId);
        TaUser taUser = taUserMapper.selectOne(taUserQueryWrapper);
        return taUser;
    }

}
