|
@@ -0,0 +1,321 @@
|
|
|
+package com.ym.mec.biz.service.impl;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Propagation;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.huifu.adapay.model.payment.Payment;
|
|
|
+import com.ym.mec.biz.dal.dao.SysConfigDao;
|
|
|
+import com.ym.mec.biz.dal.dao.TeacherDao;
|
|
|
+import com.ym.mec.biz.dal.dao.TenantEntryActivitiesDao;
|
|
|
+import com.ym.mec.biz.dal.dao.TenantPaymentOrderDao;
|
|
|
+import com.ym.mec.biz.dal.entity.SysTenantAccountDetail.TransType;
|
|
|
+import com.ym.mec.biz.dal.entity.Teacher;
|
|
|
+import com.ym.mec.biz.dal.entity.TenantEntryActivities;
|
|
|
+import com.ym.mec.biz.dal.entity.TenantEntryActivities.SuitableUser;
|
|
|
+import com.ym.mec.biz.dal.entity.TenantPaymentOrder;
|
|
|
+import com.ym.mec.biz.dal.entity.TenantPaymentOrder.TenantPaymentType;
|
|
|
+import com.ym.mec.biz.dal.enums.DealStatusEnum;
|
|
|
+import com.ym.mec.biz.service.PayService;
|
|
|
+import com.ym.mec.biz.service.SysTenantAccountService;
|
|
|
+import com.ym.mec.biz.service.TenantPaymentOrderService;
|
|
|
+import com.ym.mec.common.dal.BaseDAO;
|
|
|
+import com.ym.mec.common.exception.BizException;
|
|
|
+import com.ym.mec.common.service.IdGeneratorService;
|
|
|
+import com.ym.mec.common.service.impl.BaseServiceImpl;
|
|
|
+import com.ym.mec.thirdparty.adapay.Pay;
|
|
|
+import com.ym.mec.thirdparty.yqpay.Msg;
|
|
|
+import com.ym.mec.thirdparty.yqpay.RsqMsg;
|
|
|
+import com.ym.mec.thirdparty.yqpay.YqPayFeignService;
|
|
|
+import com.ym.mec.thirdparty.yqpay.YqPayUtil;
|
|
|
+import com.ym.mec.util.date.DateUtil;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class TenantPaymentOrderServiceImpl extends BaseServiceImpl<Long, TenantPaymentOrder> implements TenantPaymentOrderService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private TenantPaymentOrderDao tenantPaymentOrderDao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private TenantEntryActivitiesDao tenantEntryActivitiesDao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IdGeneratorService idGeneratorService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private PayService payService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysConfigDao sysConfigDao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private TeacherDao teacherDao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysTenantAccountService sysTenantAccountService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private YqPayFeignService yqPayFeignService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public BaseDAO<Long, TenantPaymentOrder> getDAO() {
|
|
|
+ return tenantPaymentOrderDao;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
|
|
|
+ public Map<String, Object> createOrder(Integer userId, Integer activitiesId) {
|
|
|
+
|
|
|
+ Teacher teacher = teacherDao.get(userId);
|
|
|
+ if (teacher == null) {
|
|
|
+ throw new BizException("用户信息不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ Integer organId = teacher.getOrganId();
|
|
|
+
|
|
|
+ TenantEntryActivities tenantEntryActivities = tenantEntryActivitiesDao.get(activitiesId);
|
|
|
+ if (tenantEntryActivities == null) {
|
|
|
+ throw new BizException("活动不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ Date date = new Date();
|
|
|
+ // 判断活动是否有效
|
|
|
+ if (tenantEntryActivities.getDelFlag() == true) {
|
|
|
+ throw new BizException("活动已下架");
|
|
|
+ }
|
|
|
+ if (date.before(tenantEntryActivities.getStartDate())) {
|
|
|
+ throw new BizException("活动未开始");
|
|
|
+ }
|
|
|
+ if (date.after(tenantEntryActivities.getEndDate())) {
|
|
|
+ throw new BizException("活动已结束");
|
|
|
+ }
|
|
|
+
|
|
|
+ int purchaseTimes = 0; // 购买次数
|
|
|
+ // 查询用户订单
|
|
|
+ List<TenantPaymentOrder> orderList = tenantPaymentOrderDao.queryByUserId(userId);
|
|
|
+ if (orderList != null && orderList.size() > 0) {
|
|
|
+ for (TenantPaymentOrder po : orderList) {
|
|
|
+ if (po.getStatus() == DealStatusEnum.ING || po.getStatus() == DealStatusEnum.SUCCESS) {
|
|
|
+ ++purchaseTimes;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 是否满足条件
|
|
|
+ if (tenantEntryActivities.getSuitableUser() == SuitableUser.NEW) {
|
|
|
+ if (purchaseTimes > 0) {
|
|
|
+ throw new BizException("您已参与过当前活动,每人只能参与一次");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ TenantPaymentOrder tenantPaymentOrder = new TenantPaymentOrder();
|
|
|
+ tenantPaymentOrder.setUserId(userId);
|
|
|
+ tenantPaymentOrder.setOrderNo(idGeneratorService.generatorId("tenant_payment") + "");
|
|
|
+ tenantPaymentOrder.setType(TenantPaymentType.RECHARGE);
|
|
|
+ tenantPaymentOrder.setExpectAmount(tenantEntryActivities.getDiscountPrice());
|
|
|
+ tenantPaymentOrder.setStatus(DealStatusEnum.ING);
|
|
|
+ tenantPaymentOrder.setCreateTime(date);
|
|
|
+ tenantPaymentOrder.setUpdateTime(date);
|
|
|
+ tenantPaymentOrder.setVersion(0);
|
|
|
+ tenantPaymentOrder.setOrganId(organId);
|
|
|
+ tenantPaymentOrder.setActivitiesId(activitiesId);
|
|
|
+ tenantPaymentOrderDao.insert(tenantPaymentOrder);
|
|
|
+
|
|
|
+ String baseApiUrl = sysConfigDao.findConfigValue("base_api_url");
|
|
|
+
|
|
|
+ // 分类费用 course,instrument,accessories,other
|
|
|
+ Map<String, BigDecimal> classFee = new HashMap<>();
|
|
|
+ classFee.put("course", BigDecimal.ZERO);
|
|
|
+ classFee.put("instrument", BigDecimal.ZERO);
|
|
|
+ classFee.put("accessories", BigDecimal.ZERO);
|
|
|
+ classFee.put("other", tenantPaymentOrder.getExpectAmount());
|
|
|
+
|
|
|
+ try {
|
|
|
+
|
|
|
+ Map<String, Object> payMap = payService.getPayMap(tenantPaymentOrder.getExpectAmount(), tenantPaymentOrder.getOrderNo(), baseApiUrl
|
|
|
+ + "/api-teacher/teacherOrder/notify", baseApiUrl + "/api-teacher/teacherOrder/paymentResult?orderNo=" + tenantPaymentOrder.getOrderNo(),
|
|
|
+ "商户入驻", "商户充值", userId, classFee, organId);
|
|
|
+
|
|
|
+ Map<String, BigDecimal> routingFee = (Map<String, BigDecimal>) payMap.get("routingFee");
|
|
|
+ tenantPaymentOrder.setComAmount(routingFee.get("COM"));
|
|
|
+ tenantPaymentOrder.setPerAmount(routingFee.get("PER"));
|
|
|
+ tenantPaymentOrder.setMerNos((String) payMap.get("routingMerNos"));
|
|
|
+ tenantPaymentOrder.setPaymentChannel((String) payMap.get("type"));
|
|
|
+ tenantPaymentOrder.setUpdateTime(date);
|
|
|
+ tenantPaymentOrderDao.update(tenantPaymentOrder);
|
|
|
+
|
|
|
+ return payMap;
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new BizException("调用支付接口出错", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
|
|
|
+ public boolean paymentForCallback(TenantPaymentOrder tenantPaymentOrder) {
|
|
|
+
|
|
|
+ Integer activitiesId = tenantPaymentOrder.getActivitiesId();
|
|
|
+
|
|
|
+ Date date = new Date();
|
|
|
+ tenantPaymentOrder.setUpdateTime(date);
|
|
|
+ tenantPaymentOrderDao.update(tenantPaymentOrder);
|
|
|
+
|
|
|
+ Integer userId = tenantPaymentOrder.getUserId();
|
|
|
+
|
|
|
+ if (tenantPaymentOrder.getStatus() == DealStatusEnum.SUCCESS) {
|
|
|
+
|
|
|
+ TenantEntryActivities tenantEntryActivities = tenantEntryActivitiesDao.get(activitiesId);
|
|
|
+ if (tenantEntryActivities == null) {
|
|
|
+ throw new BizException("活动找不到");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新账户表信息
|
|
|
+ sysTenantAccountService.update(userId, tenantEntryActivities.getPurchaseMinutes() + tenantEntryActivities.getGiveMinutes(), TransType.RECHARGE, "",
|
|
|
+ tenantEntryActivities.getDiscountPrice(), "");
|
|
|
+ } else {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void queryOrderStatusFromRemote() {
|
|
|
+ try {
|
|
|
+ yqPayQuery();
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new BizException("查询订单状态出现异常");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ adaPayQuery();
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new BizException("查询订单状态出现异常");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void yqPayQuery() throws Exception {
|
|
|
+ List<TenantPaymentOrder> payingOrders = tenantPaymentOrderDao.findOrdersByStatus(DealStatusEnum.ING, "YQPAY");
|
|
|
+
|
|
|
+ if (payingOrders.size() == 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<String> orderNoList = payingOrders.stream().map(TenantPaymentOrder::getOrderNo).collect(Collectors.toList());
|
|
|
+ String merOrderNos = payingOrders.stream().map(TenantPaymentOrder::getOrderNo).collect(Collectors.joining(","));
|
|
|
+
|
|
|
+ String notifyUrl = ""; // 回调地址
|
|
|
+ Map<String, Object> resultMap = new LinkedHashMap<>();
|
|
|
+ resultMap.put("merOrderNoList", merOrderNos);
|
|
|
+ Map<String, Object> requestMap = YqPayUtil.getRequestMap(notifyUrl, resultMap);
|
|
|
+
|
|
|
+ RsqMsg rsqMsg = new RsqMsg(requestMap);
|
|
|
+
|
|
|
+ Msg queryRs = yqPayFeignService.orderQuery(rsqMsg);
|
|
|
+
|
|
|
+ if (queryRs.getCode().equals("88")) {
|
|
|
+ // 更新订单状态
|
|
|
+ String[] statusArr = { "0", "1", "7" };
|
|
|
+ String responseParameters = queryRs.getResponseParameters();
|
|
|
+ List<Map<String, String>> responseList = JSON.parseObject(responseParameters, List.class);
|
|
|
+ for (Map<String, String> response : responseList) {
|
|
|
+ Map<String, String> rpMap = response;
|
|
|
+ String channelType = rpMap.get("channelType").equals("1") ? "WXPay" : (rpMap.get("channelType").equals("2") ? "Alipay" : "quickPay");
|
|
|
+ rpMap.put("channelType", channelType);
|
|
|
+
|
|
|
+ if (orderNoList.contains(rpMap.get("merOrderNo"))) {
|
|
|
+ orderNoList.remove(rpMap.get("merOrderNo"));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Arrays.asList(statusArr).contains(rpMap.get("tradeState"))) {
|
|
|
+ try {
|
|
|
+ DealStatusEnum status = rpMap.get("tradeState").equals("1") ? DealStatusEnum.SUCCESS : DealStatusEnum.FAILED;
|
|
|
+ TenantPaymentOrder order = tenantPaymentOrderDao.findOrderByOrderNo(rpMap.get("merOrderNo"));
|
|
|
+ if (order == null || !order.getStatus().equals(DealStatusEnum.ING)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (status.equals(DealStatusEnum.SUCCESS)) {
|
|
|
+ order.setPayTime(new Date());
|
|
|
+ } else {
|
|
|
+ order.setMemo(rpMap.get("remarks"));
|
|
|
+ }
|
|
|
+ order.setStatus(status);
|
|
|
+ order.setTransNo(rpMap.get("orderNo"));
|
|
|
+ order.setPaymentBusinessChannel(channelType);
|
|
|
+ order.setActualAmount(new BigDecimal(rpMap.get("payAmount")));
|
|
|
+ paymentForCallback(order);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Date date = new Date();
|
|
|
+ for (TenantPaymentOrder po : payingOrders) {
|
|
|
+ if (orderNoList.contains(po.getOrderNo())) {
|
|
|
+ // 超过30分钟的关闭订单
|
|
|
+ if (DateUtil.addMinutes(po.getCreateTime(), 30).before(date)) {
|
|
|
+ po.setStatus(DealStatusEnum.FAILED);
|
|
|
+ po.setMemo("超时未支付关闭");
|
|
|
+ paymentForCallback(po);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void adaPayQuery() throws Exception {
|
|
|
+ List<TenantPaymentOrder> payingOrders = tenantPaymentOrderDao.findOrdersByStatus(DealStatusEnum.ING, "ADAPAY");
|
|
|
+ if (payingOrders.size() == 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> orderNoList = new ArrayList<String>();
|
|
|
+
|
|
|
+ for (TenantPaymentOrder payingOrder : payingOrders) {
|
|
|
+ if (payingOrder.getTransNo() == null) {
|
|
|
+ orderNoList.add(payingOrder.getOrderNo());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Payment payment = new Pay().queryPayment(payingOrder.getTransNo());
|
|
|
+ Map<String, String> rpMap = new HashMap<>();
|
|
|
+ rpMap.put("merOrderNo", payingOrder.getOrderNo());
|
|
|
+ rpMap.put("remarks", payment.getReason());
|
|
|
+ rpMap.put("orderNo", payment.getId());
|
|
|
+ rpMap.put("channelType", payment.getPayChannel());
|
|
|
+ if (payment.getStatus().equals("succeeded")) {
|
|
|
+ rpMap.put("tradeState", "1");
|
|
|
+ }
|
|
|
+ if (payment.getStatus().equals("failed")) {
|
|
|
+ rpMap.put("tradeState", "0");
|
|
|
+ }
|
|
|
+ if (payment.getStatus().equals("pending")) {
|
|
|
+ orderNoList.add(payingOrder.getOrderNo());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Date date = new Date();
|
|
|
+ for (TenantPaymentOrder po : payingOrders) {
|
|
|
+ if (orderNoList.contains(po.getOrderNo())) {
|
|
|
+ // 超过30分钟的关闭订单
|
|
|
+ if (DateUtil.addMinutes(po.getCreateTime(), 30).before(date)) {
|
|
|
+ po.setStatus(DealStatusEnum.FAILED);
|
|
|
+ po.setMemo("超时未支付关闭");
|
|
|
+ paymentForCallback(po);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|