LiveTask.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. package com.fs.task;
  2. import com.fs.common.annotation.QuartzRunnable;
  3. import com.fs.common.core.redis.RedisCache;
  4. import com.fs.erp.domain.ErpDeliverys;
  5. import com.fs.erp.domain.ErpOrderQuery;
  6. import com.fs.erp.dto.ErpOrderQueryRequert;
  7. import com.fs.erp.dto.ErpOrderQueryResponse;
  8. import com.fs.erp.service.FsJstAftersalePushService;
  9. import com.fs.erp.service.IErpOrderService;
  10. import com.fs.erp.utils.ErpContextHolder;
  11. import com.fs.express.FsStoreDeliversService;
  12. import com.fs.common.utils.StringUtils;
  13. import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
  14. import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
  15. import com.fs.live.domain.LiveOrderPayment;
  16. import com.fs.live.mapper.LiveOrderPaymentMapper;
  17. import com.fs.live.vo.LiveOrderPaymentVo;
  18. import com.fs.pay.pay.domain.OrderResult;
  19. import com.fs.pay.pay.dto.OrderQueryDTO;
  20. import com.fs.pay.pay.service.PayService;
  21. import com.fs.huifuPay.service.HuiFuService;
  22. import com.fs.live.utils.redis.RedisBatchHandler;
  23. import com.fs.live.domain.LiveAfterSales;
  24. import com.fs.live.domain.LiveOrder;
  25. import com.fs.live.service.*;
  26. import com.fs.store.domain.FsExpress;
  27. import com.fs.store.enums.OrderLogEnum;
  28. import com.fs.store.mapper.*;
  29. import com.fs.store.param.LiveAfterSalesAudit1Param;
  30. import com.fs.store.service.*;
  31. import org.apache.commons.collections4.CollectionUtils;
  32. import org.apache.commons.lang.ObjectUtils;
  33. import org.slf4j.Logger;
  34. import org.slf4j.LoggerFactory;
  35. import org.springframework.beans.factory.annotation.Autowired;
  36. import org.springframework.scheduling.annotation.Scheduled;
  37. import org.springframework.stereotype.Component;
  38. import java.text.ParseException;
  39. import java.text.SimpleDateFormat;
  40. import java.util.List;
  41. import java.util.concurrent.TimeUnit;
  42. import static com.fs.live.utils.redis.RedisBatchHandler.CONSUME_INTERVAL;
  43. /**
  44. * 定时任务调度
  45. * @author fs
  46. */
  47. @Component("liveTask")
  48. public class LiveTask {
  49. Logger logger = LoggerFactory.getLogger(LiveTask.class);
  50. @Autowired
  51. private ILiveOrderService liveOrderService;
  52. @Autowired
  53. private LiveOrderPaymentMapper liveOrderPaymentMapper;
  54. @Autowired
  55. private HuiFuService huiFuService;
  56. @Autowired
  57. private PayService ybPayService;
  58. @Autowired
  59. private ILiveAfterSalesService afterSalesService;
  60. @Autowired
  61. private IErpOrderService erpOrderService;
  62. @Autowired
  63. private IFsExpressService expressService;
  64. @Autowired
  65. private ILiveOrderLogsService orderLogsService;
  66. @Autowired
  67. private FsWarehousesMapper fsWarehousesMapper;
  68. @Autowired
  69. public FsJstAftersalePushService fsJstAftersalePushService;
  70. @Autowired
  71. public RedisBatchHandler redisBatchHandler;
  72. @Autowired
  73. private IFsUserService fsUserService;
  74. @Autowired
  75. private RedisCache redisCache;
  76. private static final String APP_USER_SYNC_TASK_LOCK_KEY = "task:live:app_user_sync:lock";
  77. private static final long APP_USER_SYNC_TASK_LOCK_SECONDS = 600L;
  78. /** 两个 APP 用户同步任务错峰启动间隔(秒) */
  79. private static final long APP_USER_SYNC_TASK_STAGGER_SECONDS = 15L;
  80. // 订单银行回调数据丢失补偿
  81. public void recoveryBankOrder() {
  82. // 查询出来最近15分钟的订单 待支付 未退款
  83. List<LiveOrder> list = liveOrderService.selectBankOrder();
  84. if (CollectionUtils.isEmpty(list)) {
  85. return;
  86. }
  87. for (LiveOrder order : list) {
  88. try {
  89. LiveOrderPaymentVo payment = liveOrderPaymentMapper.selectLiveOrderPaymentByPaymentIdNew(order.getOrderId());
  90. if (payment == null || payment.getStatus() == null || payment.getStatus() != 0) {
  91. continue;
  92. }
  93. if (StringUtils.isEmpty(payment.getTradeNo()) || StringUtils.isEmpty(payment.getPayMode())) {
  94. continue;
  95. }
  96. String payMode = payment.getPayMode();
  97. if ("hf".equals(payMode)) {
  98. V2TradePaymentScanpayQueryRequest request = new V2TradePaymentScanpayQueryRequest();
  99. request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
  100. request.setOrgHfSeqId(payment.getTradeNo());
  101. HuiFuQueryOrderResult o = huiFuService.queryOrder(request);
  102. logger.info("直播订单补偿 汇付查询 orderId={} resp={}", order.getOrderId(), o);
  103. if (o != null && "00000000".equals(o.getResp_code()) && "S".equals(o.getTrans_stat())) {
  104. String[] parts = o.getOrg_req_seq_id().split("-");
  105. if (parts.length >= 2 && "live".equals(parts[0])) {
  106. liveOrderService.payConfirm(1, null, parts[1], o.getOrg_hf_seq_id(), o.getOut_trans_id(), o.getParty_order_id());
  107. }
  108. }
  109. } else if ("yb".equals(payMode)) {
  110. OrderQueryDTO q = new OrderQueryDTO();
  111. q.setUpOrderId(payment.getTradeNo());
  112. OrderResult orderResult = ybPayService.getOrder(q);
  113. if (orderResult == null) {
  114. continue;
  115. }
  116. if ("4".equals(orderResult.getState()) || "5".equals(orderResult.getState())) {
  117. continue;
  118. }
  119. if (!"0".equals(orderResult.getState()) || !"100".equals(orderResult.getStatus())) {
  120. continue;
  121. }
  122. String[] parts = orderResult.getLowOrderId().split("-");
  123. if (parts.length >= 2 && "live".equals(parts[0])) {
  124. liveOrderService.payConfirm(1, null, parts[1], payment.getTradeNo(), orderResult.getBankTrxId(), orderResult.getBankOrderId());
  125. }
  126. } else if ("tzbk".equals(payMode)) {
  127. logger.debug("直播订单补偿跳过台州银行支付 orderId={}", order.getOrderId());
  128. }
  129. } catch (Exception e) {
  130. logger.error("直播订单银行补偿失败 orderId={}", order.getOrderId(), e);
  131. }
  132. }
  133. }
  134. /**
  135. * 超时订单自动取消
  136. */
  137. @QuartzRunnable(name = "超时订单自动取消")
  138. public void orderCancel(){
  139. liveOrderService.orderCancel();
  140. }
  141. /**
  142. * 发货任务
  143. */
  144. @QuartzRunnable(name = "发货任务")
  145. public void deliveryOp() {
  146. List<LiveOrder> list = liveOrderService.selectDeliverPenddingData();
  147. for (LiveOrder order : list) {
  148. String orderCode = order.getOrderCode();
  149. ErpOrderQueryRequert request = new ErpOrderQueryRequert();
  150. request.setCode(order.getExtendOrderId());
  151. try {
  152. // 根据仓库code找erp
  153. if (com.fs.common.utils.StringUtils.isNotBlank(order.getStoreHouseCode())) {
  154. String erp = fsWarehousesMapper.selectErpByCode(order.getStoreHouseCode());
  155. ErpContextHolder.setErpType(erp);
  156. }
  157. ErpOrderQueryResponse response = erpOrderService.getOrderLive(request);
  158. if (CollectionUtils.isNotEmpty(response.getOrders())) {
  159. for (ErpOrderQuery orderQuery : response.getOrders()) {
  160. if (CollectionUtils.isNotEmpty(orderQuery.getDeliverys())) {
  161. // 部分发货或者全部发货
  162. if (ObjectUtils.equals(orderQuery.getDelivery_state(), 1) || ObjectUtils.equals(orderQuery.getDelivery_state(), 2)) {
  163. orderLogsService.create(order.getOrderId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
  164. OrderLogEnum.DELIVERY_GOODS.getDesc());
  165. for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
  166. FsExpress express = expressService.selectFsExpressByOmsCode(delivery.getExpress_code());
  167. if (express == null) {
  168. logger.warn("当前express_code: {} 不存在!", delivery.getExpress_code());
  169. continue;
  170. }
  171. if (delivery.getDelivery()) {
  172. liveOrderService.deliveryOrder(orderCode, delivery.getMail_no(),
  173. delivery.getExpress_code(), delivery.getExpress_name());
  174. }
  175. }
  176. logger.info("订单 {} 发货信息同步成功", order.getOrderCode());
  177. }
  178. }
  179. }
  180. }
  181. } catch (Exception e) {
  182. logger.error(String.format("[发货任务]调用erp查询接口失败!原因: %s", e));
  183. }
  184. }
  185. }
  186. /**
  187. * 同步近三天直播订单关联的APP用户数据
  188. */
  189. @QuartzRunnable(name = "同步APP用户数据")
  190. public void syncAppUser() {
  191. if (!tryAcquireAppUserSyncLock()) {
  192. logger.debug("同步APP用户数据任务跳过,其他任务正在执行");
  193. return;
  194. }
  195. try {
  196. fsUserService.syncAppUsersForRecentLiveOrders(3);
  197. } catch (Exception e) {
  198. logger.error("同步APP用户数据失败", e);
  199. } finally {
  200. releaseAppUserSyncLock();
  201. }
  202. }
  203. /**
  204. * 从 Redis 拉取下单时缓存的待同步 APP 用户并同步
  205. */
  206. @QuartzRunnable(name = "同步APP用户数据(Redis)")
  207. public void syncAppUserFromRedis() {
  208. try {
  209. Thread.sleep(APP_USER_SYNC_TASK_STAGGER_SECONDS * 1000);
  210. } catch (InterruptedException e) {
  211. Thread.currentThread().interrupt();
  212. return;
  213. }
  214. if (!tryAcquireAppUserSyncLock()) {
  215. logger.debug("Redis同步APP用户数据任务跳过,其他任务正在执行");
  216. return;
  217. }
  218. try {
  219. fsUserService.syncPendingAppUsersFromRedis();
  220. } catch (Exception e) {
  221. logger.error("Redis同步APP用户数据失败", e);
  222. } finally {
  223. releaseAppUserSyncLock();
  224. }
  225. }
  226. private boolean tryAcquireAppUserSyncLock() {
  227. return redisCache.setIfAbsent(APP_USER_SYNC_TASK_LOCK_KEY, "1", APP_USER_SYNC_TASK_LOCK_SECONDS, TimeUnit.SECONDS);
  228. }
  229. private void releaseAppUserSyncLock() {
  230. redisCache.deleteObject(APP_USER_SYNC_TASK_LOCK_KEY);
  231. }
  232. /**
  233. * 退款自动处理 24小时未审核自动审核通过 每小时执行一次
  234. */
  235. @QuartzRunnable(name = "直播售后自动审核")
  236. public void refundOp() {
  237. //获取所有退款申请
  238. List<LiveAfterSales> list = afterSalesService.selectLiveAfterSalesByDoAudit();
  239. if (list != null) {
  240. for (LiveAfterSales afterSales : list) {
  241. //仅退款
  242. // if (afterSales.getServiceType().equals(0)) {
  243. LiveAfterSalesAudit1Param audit1Param = new LiveAfterSalesAudit1Param();
  244. audit1Param.setSalesId(afterSales.getId());
  245. audit1Param.setOperator("平台");
  246. afterSalesService.audit1(audit1Param);
  247. // }
  248. }
  249. }
  250. }
  251. /**
  252. * 批量推管易
  253. * @throws ParseException 解析异常
  254. */
  255. @QuartzRunnable(name = "批量推管易")
  256. public void updateOrderItem() throws ParseException {
  257. List<Long> ids = liveOrderService.selectOrderIdByNoErp();
  258. for (Long id : ids) {
  259. try{
  260. liveOrderService.createOmsOrder(id);
  261. }catch (Exception e){
  262. logger.error("推送管易失败 {}",id,e);
  263. }
  264. }
  265. }
  266. @Autowired
  267. FsStoreDeliversService fsStoreDeliverService;
  268. /**
  269. * 同步物流状态
  270. */
  271. @QuartzRunnable(name = "直播同步物流状态")
  272. public void syncExpress() {
  273. List<Long> ids = liveOrderService.selectSyncExpressIds();
  274. for (Long id : ids) {
  275. liveOrderService.syncExpress(id);
  276. fsStoreDeliverService.finishOrder(id,1);
  277. }
  278. }
  279. /**
  280. * 更新发货状态
  281. */
  282. @QuartzRunnable(name = "直播发货任务")
  283. public void updateExpress() {
  284. List<LiveOrder> list = liveOrderService.selectUpdateExpress();
  285. for (LiveOrder order : list) {
  286. try{
  287. liveOrderService.syncDeliveryOrder(order);
  288. }catch (Exception e) {
  289. logger.error("获取订单是否发货失败!原因: ",e);
  290. }
  291. }
  292. }
  293. /**
  294. * 更新流量
  295. */
  296. @Scheduled(fixedRate = CONSUME_INTERVAL)
  297. public void insertLiveTrralog() {
  298. redisBatchHandler.consumeBatchData();
  299. }
  300. }