admin
2021-04-19 eb7f3343af839a7c71f16e8ada2b25d5e2201c08
src/main/java/com/yeshi/buwan/service/imp/order/OrderServiceImpl.java
@@ -2,10 +2,10 @@
import com.alipay.api.AlipayApiException;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.yeshi.buwan.dao.vip.VIPOrderRecordDao;
import com.yeshi.buwan.dao.vip.OrderRecordDao;
import com.yeshi.buwan.domain.vip.OrderRecord;
import com.yeshi.buwan.domain.vip.OrderType;
import com.yeshi.buwan.domain.vip.UserVIPInfo;
import com.yeshi.buwan.domain.vip.VIPOrderRecord;
import com.yeshi.buwan.domain.vip.VIPPriceType;
import com.yeshi.buwan.dto.order.PayWayInfoDTO;
import com.yeshi.buwan.exception.PPTVException;
@@ -15,6 +15,7 @@
import com.yeshi.buwan.exception.vip.VIPException;
import com.yeshi.buwan.pptv.PPTVVipManager;
import com.yeshi.buwan.service.inter.order.OrderService;
import com.yeshi.buwan.service.manager.GoldCornManager;
import com.yeshi.buwan.util.Constant;
import com.yeshi.buwan.util.RedisManager;
import com.yeshi.buwan.util.StringUtil;
@@ -42,13 +43,12 @@
@Service
public class OrderServiceImpl implements OrderService {
    private static Logger logger = LoggerFactory.getLogger("OrderService");
    private static Logger orderLogger = LoggerFactory.getLogger("order");
    @Resource
    private VIPOrderRecordDao vipOrderRecordDao;
    private OrderRecordDao vipOrderRecordDao;
    @Resource
    private PPTVVipManager pptvVipManager;
@@ -56,20 +56,42 @@
    @Resource
    private RedisManager redisManager;
    @Resource
    private GoldCornManager goldCornManager;
    @Transactional(rollbackFor = Exception.class)
    @Override
    public VIPOrderRecord createOrder(VIPOrderRecord record) throws OrderException {
        if (record.getMoney() == null || record.getType() == null || record.getOrderType() == null || record.getUid() == null) {
    public OrderRecord createOrder(OrderRecord record) throws OrderException {
        if (record.getMoney() == null || (record.getType() == null && record.getVideoInfoId() == null) || record.getOrderType() == null || record.getUid() == null) {
            throw new OrderException(1, "参数不完整");
        }
        if (record.getState() == null) {
            record.setState(VIPOrderRecord.STATE_NOT_PAY);
            record.setState(OrderRecord.STATE_NOT_PAY);
        }
        if (record.getCreateTime() == null) {
            record.setCreateTime(new Date());
        }
        if (record.getPayWay() == OrderRecord.PAY_WAY_WX) {
            if (record.getGoldCorn() != null && record.getGoldCorn() > 0) {
                if (record.getMoney().compareTo(new BigDecimal("0")) == 0) {
                    record.setPayWay(OrderRecord.PAY_WAY_GOLDCORN);
                } else {
                    record.setPayWay(OrderRecord.PAY_WAY_WX_GOLDCORN);
                }
            }
        } else if (record.getPayWay() == OrderRecord.PAY_WAY_ALIPAY) {
            if (record.getGoldCorn() != null && record.getGoldCorn() > 0) {
                if (record.getMoney().compareTo(new BigDecimal("0")) == 0) {
                    record.setPayWay(OrderRecord.PAY_WAY_GOLDCORN);
                } else {
                    record.setPayWay(OrderRecord.PAY_WAY_ALIPAY_GOLDCORN);
                }
            }
        }
        record.setMoneyPay(false);
        record.setGoldCornPay(false);
@@ -80,33 +102,52 @@
    }
    @Transactional(rollbackFor = Exception.class)
//    @GlobalTransactional(timeoutMills = 30000, name = "buwan-order", rollbackFor = Exception.class)
    @Override
    public PayWayInfoDTO payOrder(VIPOrderRecord record) throws OrderException, GoldCornException, PayException {
        //TODO 影视豆支付
    public PayWayInfoDTO payOrder(OrderRecord record) throws OrderException, GoldCornException, PayException, VIPException, PPTVException {
        String orderNo = VIPOrderUtil.getOutOrderNo(record.getOrderType(), record.getId());
        switch (record.getPayWay()) {
            case VIPOrderRecord
            case OrderRecord
                    .PAY_WAY_ALIPAY_GOLDCORN:
                //TODO 扣影视豆
                try {
                    goldCornManager.consumeGoldCorn(record, record.getGoldCorn());
                } catch (Exception e) {
                    throw new GoldCornException(1, "影视豆扣除出错");
                }
                paySuccess(record.getId(), OrderRecord.PAY_WAY_GOLDCORN, null, new Date());
                orderLogger.info("订单影视豆支付成功:id-{}", record.getId());
            case VIPOrderRecord
            case OrderRecord
                    .PAY_WAY_ALIPAY: {
                if (record.getMoney() != null && record.getMoney().compareTo(new BigDecimal(0)) == 0) {
                    return new PayWayInfoDTO(0, VipUtil.getPaySuccessUrl(record.getId()));
                }
                //生成支付宝支付订单
                String form = VipUtil.getVipChargeAlipayForm(record.getId(), orderNo, record.getMoney());
                String form = VipUtil.getVipChargeAlipayForm(record.getId(), record.getOrderType(), orderNo, record.getMoney());
                //暂存2分钟
                String id = StringUtil.Md5(UUID.randomUUID().toString() + "#" + System.currentTimeMillis());
                redisManager.cacheCommonString(id, form, 120);
                String payUrl = Constant.HOST + "/BuWan/alipay/printPayForm?formId=" + id;
                orderLogger.info("订单创建支付宝支付链接成功:id-{} 链接-{}", record.getId(), payUrl);
                return new PayWayInfoDTO(VIPOrderRecord
                return new PayWayInfoDTO(OrderRecord
                        .PAY_WAY_ALIPAY, payUrl);
            }
            case VIPOrderRecord
            case OrderRecord
                    .PAY_WAY_WX_GOLDCORN:
                //TODO 扣影视豆
                try {
                    goldCornManager.consumeGoldCorn(record, record.getGoldCorn());
                } catch (Exception e) {
                    throw new GoldCornException(1, "影视豆扣除出错");
                }
                paySuccess(record.getId(), OrderRecord.PAY_WAY_GOLDCORN, null, new Date());
                orderLogger.info("订单影视豆支付成功:id-{} 类型-{}", record.getId(), record.getOrderType().name());
            case VIPOrderRecord
            case OrderRecord
                    .PAY_WAY_WX: {
                if (record.getMoney() != null && record.getMoney().compareTo(new BigDecimal(0)) == 0) {
                    return new PayWayInfoDTO(0, VipUtil.getPaySuccessUrl(record.getId()));
                }
                //生成微信支付订单
                try {
                    String title = "";
@@ -117,167 +158,185 @@
                    }
                    String payUrl = VipUtil.createWXOrder(record.getId(), record.getIpInfo(), orderNo, record.getMoney(), title);
                    orderLogger.info("订单创建微信支付链接成功:id-{} 链接-{}", record.getId(), payUrl);
                    return new PayWayInfoDTO(VIPOrderRecord.PAY_WAY_WX, payUrl);
                    return new PayWayInfoDTO(OrderRecord.PAY_WAY_WX, payUrl);
                } catch (Exception e) {
                    logger.error("生成微信支付订单出错", e);
                    throw new PayException(2, e.getMessage());
                }
            }
            case VIPOrderRecord.PAY_WAY_GOLDCORN: {
                //TODO 扣影视豆
                orderLogger.info("订单影视豆支付成功:id-{}", record.getId());
            case OrderRecord.PAY_WAY_GOLDCORN: {
                try {
                    goldCornManager.consumeGoldCorn(record, record.getGoldCorn());
                    orderLogger.info("订单影视豆支付成功:id-{}", record.getId());
                } catch (Exception e) {
                    throw new GoldCornException(1, "影视豆扣除出错");
                }
                paySuccess(record.getId(), OrderRecord.PAY_WAY_GOLDCORN, null, new Date());
                return new PayWayInfoDTO(0, VipUtil.getPaySuccessUrl(record.getId()));
            }
            break;
        }
        throw new OrderException(1, "支付方式不存在");
    }
    private int getPayState(VIPOrderRecord record) {
    private int getPayState(OrderRecord record) {
        switch (record.getPayWay()) {
            case VIPOrderRecord.PAY_WAY_ALIPAY:
            case VIPOrderRecord.PAY_WAY_WX:
            case OrderRecord.PAY_WAY_ALIPAY:
            case OrderRecord.PAY_WAY_WX:
                if (record.getMoneyPay() != null && record.getMoneyPay())
                    return VIPOrderRecord.STATE_PAY;
                    return OrderRecord.STATE_PAY;
                else
                    return VIPOrderRecord.STATE_NOT_PAY;
            case VIPOrderRecord.PAY_WAY_ALIPAY_GOLDCORN:
            case VIPOrderRecord.PAY_WAY_WX_GOLDCORN:
                    return OrderRecord.STATE_NOT_PAY;
            case OrderRecord.PAY_WAY_ALIPAY_GOLDCORN:
            case OrderRecord.PAY_WAY_WX_GOLDCORN:
                if (record.getMoneyPay() != null && record.getMoneyPay() && record.getGoldCornPay() != null && record.getGoldCornPay())
                    return VIPOrderRecord.STATE_PAY;
                    return OrderRecord.STATE_PAY;
                else
                    return VIPOrderRecord.STATE_NOT_PAY;
            case VIPOrderRecord.PAY_WAY_GOLDCORN:
                    return OrderRecord.STATE_NOT_PAY;
            case OrderRecord.PAY_WAY_GOLDCORN:
                if (record.getGoldCornPay() != null && record.getGoldCornPay())
                    return VIPOrderRecord.STATE_PAY;
                    return OrderRecord.STATE_PAY;
                else
                    return VIPOrderRecord.STATE_NOT_PAY;
                    return OrderRecord.STATE_NOT_PAY;
        }
        return VIPOrderRecord.STATE_NOT_PAY;
        return OrderRecord.STATE_NOT_PAY;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public VIPOrderRecord paySuccess(String id, int payWay, BigDecimal payMoney, Date payTime) throws
    public OrderRecord paySuccess(String id, int payWay, BigDecimal payMoney, Date payTime) throws
            VIPException, PPTVException {
        orderLogger.info("订单支付成功目的执行:id-{},支付方式-{},支付金额-{},支付时间-{}", id, payWay, payMoney, payTime.getTime());
        Session session = vipOrderRecordDao.getSession();
        //修改记录
        Query query = session.createSQLQuery("select * from wk_vip_order_record r where r.id=? for update").addEntity(VIPOrderRecord.class).setCacheable(false).setParameter(0, id);
        List<VIPOrderRecord> list = query.list();
        if (list != null && list.size() > 0) {
            VIPOrderRecord record = list.get(0);
            if (record.getState() != VIPOrderRecord.STATE_NOT_PAY)
                throw new VIPException(1, "订单未处于待支付状态");
            if (record.getPayWay() != VIPOrderRecord.PAY_WAY_GOLDCORN) {
                record.setPayMoney(payMoney);
                record.setMoneyPay(true);
            } else {
                record.setGoldCornPay(true);
            }
            record.setPayTime(payTime);
            record.setUpdateTime(new Date());
            record.setState(getPayState(record));
            //已经支付成功
            if (record.getState() == VIPOrderRecord.STATE_PAY) {
                session.createSQLQuery("insert into wk_vip_order_pay_success(id,create_time) value(?,now())").setParameter(0, id).executeUpdate();
            }
            if (record.getOrderType() == OrderType.vip) {
                Date[] expireDate = addExpireTime(session, record.getUid(), payTime, record.getType());
                record.setVipStartTime(expireDate[0]);
                record.setVipEndTime(expireDate[1]);
                if (expireDate == null) {
                    throw new VIPException(2, "添加用户会员时间出错");
                }
                session.update(record);
                if (record.getState() == VIPOrderRecord.STATE_PAY) {
                    orderLogger.info("订单全部支付成功:id-{}", id);
                    //购买VIP
                    pptvVipManager.buyVIP(record);
                    orderLogger.info("购买VIP成功:id-{}", id);
                } else {
                    orderLogger.info("订单部分支付成功:id-{}", id);
                }
            } else if (record.getOrderType() == OrderType.video) {
                record.setVipStartTime(payTime);
                //7天之内有效
                record.setVipEndTime(new Date(payTime.getTime() + 1000 * 60 * 60L * 24 * 7));
                session.update(record);
                //单片购买成功(7天有效期)
                if (record.getState() == VIPOrderRecord.STATE_PAY) {
                    orderLogger.info("订单全部支付成功:id-{}", id);
                    //购买单片
                    pptvVipManager.buyVideo(record);
                    orderLogger.info("购买单片成功:id-{}", id);
                } else {
                    orderLogger.info("订单部分支付成功:id-{}", id);
                }
            }
            return record;
        } else {
        Query query = session.createSQLQuery("select * from wk_vip_order_record r where r.id=? for update").addEntity(OrderRecord.class).setCacheable(false).setParameter(0, id);
        List<OrderRecord> list = query.list();
        if (list == null || list.size() == 0)
            throw new VIPException(10, "订单不存在");
        OrderRecord record = list.get(0);
        if (record.getState() != OrderRecord.STATE_NOT_PAY)
            throw new VIPException(1, "订单未处于待支付状态");
        if (payWay != OrderRecord.PAY_WAY_GOLDCORN) {
            record.setPayMoney(payMoney);
            record.setMoneyPay(true);
        } else {
            record.setGoldCornPay(true);
        }
        record.setPayTime(payTime);
        record.setUpdateTime(new Date());
        record.setState(getPayState(record));
        //已经支付成功
        if (record.getState() == OrderRecord.STATE_PAY) {
            session.createSQLQuery("insert into wk_vip_order_pay_success(id,create_time) value(?,now())").setParameter(0, id).executeUpdate();
        }
        if (record.getOrderType() == OrderType.vip) {
            Date[] expireDate = addExpireTime(session, record.getUid(), payTime, record.getType());
            record.setVipStartTime(expireDate[0]);
            record.setVipEndTime(expireDate[1]);
            if (expireDate == null) {
                throw new VIPException(2, "添加用户会员时间出错");
            }
            session.update(record);
            if (record.getState() == OrderRecord.STATE_PAY) {
                orderLogger.info("订单全部支付成功:id-{}", id);
                //购买VIP
                pptvVipManager.buyVIP(record);
                orderLogger.info("购买VIP成功:id-{}", id);
            } else {
                orderLogger.info("订单部分支付成功:id-{}", id);
            }
        } else if (record.getOrderType() == OrderType.video) {
            record.setVipStartTime(payTime);
            //7天之内有效
            record.setVipEndTime(new Date(payTime.getTime() + 1000 * 60 * 60L * 24 * 7));
            session.update(record);
            //单片购买成功(7天有效期)
            if (record.getState() == OrderRecord.STATE_PAY) {
                orderLogger.info("订单全部支付成功:id-{}", id);
                //购买单片
                pptvVipManager.buyVideo(record);
                orderLogger.info("购买单片成功:id-{}", id);
            } else {
                orderLogger.info("订单部分支付成功:id-{}", id);
            }
        }
        return record;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void cancelOrder(String id, String reason) throws OrderException {
    public void cancelOrder(String id, String reason) throws OrderException, GoldCornException {
        Session session = vipOrderRecordDao.getSession();
        Query query = session.createSQLQuery("select * from wk_vip_order_record r where r.id=? for update").addEntity(VIPOrderRecord.class).setCacheable(false).setParameter(0, id);
        List<VIPOrderRecord> list = query.list();
        Query query = session.createSQLQuery("select * from wk_vip_order_record r where r.id=? for update").addEntity(OrderRecord.class).setCacheable(false).setParameter(0, id);
        List<OrderRecord> list = query.list();
        //订单不存在
        if (list == null || list.size() == 0)
            throw new OrderException(1, "订单不存在");
        VIPOrderRecord record = list.get(0);
        if (record.getState() == VIPOrderRecord.STATE_PAY) {
        OrderRecord record = list.get(0);
        if (record.getState() == OrderRecord.STATE_PAY) {
            throw new OrderException(1, "已支付成功的订单不能取消");
        }
        if (record.getPayWay() != VIPOrderRecord.PAY_WAY_GOLDCORN && record.getMoneyPay() != null && record.getMoneyPay()) {
        if (record.getPayWay() != OrderRecord.PAY_WAY_GOLDCORN && record.getMoneyPay() != null && record.getMoneyPay()) {
            throw new OrderException(2, "资金支付成功的订单不能取消");
        }
        //返回豆
        if (record.getGoldCornPay() != null && record.getGoldCornPay() && record.getGoldCorn() != null && record.getGoldCorn() > 0) {
            //TODO 退回影视豆
            try {
                goldCornManager.drawbackGoldCorn(record);
            } catch (Exception e) {
                throw new GoldCornException(1, "影视豆退款失败");
            }
        }
        //设置订单状态
        record.setState(VIPOrderRecord.STATE_CANCEL);
        record.setState(OrderRecord.STATE_CANCEL);
        record.setUpdateTime(new Date());
        record.setRemarks(reason);
        vipOrderRecordDao.update(record);
        session.update(record);
        orderLogger.info("取消订单成功:id-{}", id);
    }
    @Override
    public List<OrderRecord> getCanCancelOrderList(int page, int pageSize) {
        OrderRecordDao.DaoQuery daoQuery = new OrderRecordDao.DaoQuery();
        daoQuery.state = OrderRecord.STATE_NOT_PAY;
        //30分钟未支付取消订单
        daoQuery.maxCreateTime = new Date(System.currentTimeMillis() - 1000 * 60 * 30);
        daoQuery.minCreateTime = new Date(daoQuery.maxCreateTime.getTime() - 1000 * 60 * 60L * 24);
        return vipOrderRecordDao.list(daoQuery);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public VIPOrderRecord checkOrderPayState(String id) {
        VIPOrderRecord record = vipOrderRecordDao.find(VIPOrderRecord.class, id);
        if (record.getState() == VIPOrderRecord.STATE_PAY)
    public OrderRecord checkOrderPayState(String id) {
        OrderRecord record = vipOrderRecordDao.find(OrderRecord.class, id);
        if (record.getState() == OrderRecord.STATE_PAY)
            return record;
        switch (record.getPayWay()) {
            case VIPOrderRecord.PAY_WAY_ALIPAY: {
            case OrderRecord.PAY_WAY_ALIPAY_GOLDCORN:
            case OrderRecord.PAY_WAY_ALIPAY: {
                //支付宝
                AlipayTradeQueryResponse res = null;
                try {
@@ -285,7 +344,7 @@
                    //支付成功
                    if (res.isSuccess() && "TRADE_SUCCESS".equalsIgnoreCase(res.getTradeStatus())) {
                        try {
                            return paySuccess(id, VIPOrderRecord.PAY_WAY_ALIPAY, new BigDecimal(res.getTotalAmount()), new Date());
                            return paySuccess(id, OrderRecord.PAY_WAY_ALIPAY, new BigDecimal(res.getTotalAmount()), new Date());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
@@ -296,7 +355,8 @@
            }
            break;
            case VIPOrderRecord.PAY_WAY_WX: {
            case OrderRecord.PAY_WAY_WX_GOLDCORN:
            case OrderRecord.PAY_WAY_WX: {
                //微信
                try {
                    WXPayOrderInfoV3 info = WXPayV3Util.getPayOrderInfo(VIPOrderUtil.getOutOrderNo(record.getOrderType(), id), VipUtil.getWXAPP());
@@ -316,28 +376,29 @@
    @Override
    public List<VIPOrderRecord> listOrderRecord(String uid, Integer state, int page, int pageSize) {
    public List<OrderRecord> listOrderRecord(String uid, OrderType orderType, Integer state, int page, int pageSize) {
        VIPOrderRecordDao.DaoQuery query = new VIPOrderRecordDao.DaoQuery();
        OrderRecordDao.DaoQuery query = new OrderRecordDao.DaoQuery();
        query.start = (page - 1) * pageSize;
        query.count = pageSize;
        query.uid = uid;
        query.state = state;
        query.orderType = orderType;
        return vipOrderRecordDao.list(query);
    }
    @Override
    public long countOrderRecord(String uid, Integer state) {
        VIPOrderRecordDao.DaoQuery query = new VIPOrderRecordDao.DaoQuery();
    public long countOrderRecord(String uid, OrderType orderType, Integer state) {
        OrderRecordDao.DaoQuery query = new OrderRecordDao.DaoQuery();
        query.uid = uid;
        query.state = state;
        query.orderType = orderType;
        return vipOrderRecordDao.count(query);
    }
    @Override
    public VIPOrderRecord getOrderRecord(String id) {
        return vipOrderRecordDao.find(VIPOrderRecord.class, id);
    public OrderRecord getOrderRecord(String id) {
        return vipOrderRecordDao.find(OrderRecord.class, id);
    }
@@ -359,16 +420,18 @@
            UserVIPInfo vip = new UserVIPInfo();
            vip.setUid(uid);
            vip.setCreateTime(new Date());
            vip.setExpireDate(getExpireTime(payTime, null, type));
            Date[] expireDate = getExpireTime(payTime, null, type);
            vip.setExpireDate(expireDate[1]);
            session.save(vip);
            return new Date[]{payTime, vip.getExpireDate()};
            return expireDate;
        } else {
            //修改
            UserVIPInfo vipInfo = (UserVIPInfo) list.get(0);
            Date expireDate = getExpireTime(payTime, vipInfo.getExpireDate(), type);
            session.createQuery("update UserVIPInfo i set i.expireDate=? ,i.updateTime=? where i.uid=?").setParameter(0, expireDate).setParameter(1, new Date()).setParameter(2, uid).executeUpdate();
            Date[] expireDate = getExpireTime(payTime, vipInfo.getExpireDate(), type);
            session.createQuery("update UserVIPInfo i set i.expireDate=? ,i.updateTime=? where i.uid=?").setParameter(0, expireDate[1]).setParameter(1, new Date()).setParameter(2, uid).executeUpdate();
            return new Date[]{vipInfo.getExpireDate() == null ? new Date() : vipInfo.getExpireDate(), expireDate};
            return expireDate;
        }
    }
@@ -380,13 +443,18 @@
     * @param type
     * @return
     */
    private Date getExpireTime(Date payTime, Date expireTime, VIPPriceType type) {
    private Date[] getExpireTime(Date payTime, Date expireTime, VIPPriceType type) {
        Calendar calendar = Calendar.getInstance();
        if (expireTime != null) {
            calendar.setTimeInMillis(expireTime.getTime());
            //之前续期时间是否大于付款时间
            if (payTime.getTime() < expireTime.getTime())
                calendar.setTimeInMillis(expireTime.getTime());
            else
                calendar.setTimeInMillis(payTime.getTime());
        } else {
            calendar.setTimeInMillis(payTime.getTime());
        }
        long startTime = calendar.getTimeInMillis();
        if (type == VIPPriceType.day) {
            calendar.add(Calendar.DAY_OF_WEEK, 1);
        } else if (type == VIPPriceType.week) {
@@ -400,7 +468,7 @@
        } else if (type == VIPPriceType.year) {
            calendar.add(Calendar.YEAR, 1);
        }
        return new Date(calendar.getTimeInMillis());
        return new Date[]{new Date(startTime), new Date(calendar.getTimeInMillis())};
    }