import com.alibaba.fastjson2.JSON import com.dderp.business.dao.OrderDao import com.dderp.common.api.BusinessExecutor import com.dderp.common.api.ERPLockDataService import com.dderp.common.api.StoreService import com.dderp.common.api.SupplierInitService import com.dderp.common.api.flycat.OrderSearchService import com.dderp.common.api.flycat.OrderStepService import com.dderp.common.datas.* import com.dderp.common.datas.flycat.BusinessOrderStatus import com.dderp.common.entity.base.InvokeCallParams import com.dderp.common.entity.base.InvokeCallResult import com.dderp.common.entity.order.BusinessOrder import com.dderp.common.entity.order.OrderStep import com.dderp.common.entity.store.StoreInfo import com.dderp.common.entity.store.StorePlatform import com.dderp.common.http.HttpTools import com.dderp.common.tool.ERPUtils import com.dySweetFishPlugin.elasticsearch.ESClient import com.dySweetFishPlugin.sql.dao.OperatorWait import com.dySweetFishPlugin.sql.dao.TunaService import com.sweetfish.convert.json.JsonConvert import com.sweetfish.service.RetResult import groovy.json.JsonSlurper import org.apache.commons.lang3.StringUtils import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger import org.elasticsearch.action.bulk.BulkRequestBuilder import org.elasticsearch.action.bulk.BulkResponse import org.elasticsearch.action.index.IndexRequestBuilder import org.elasticsearch.action.support.WriteRequest import org.elasticsearch.action.update.UpdateRequest import org.elasticsearch.common.xcontent.XContentType import javax.annotation.Resource import java.nio.charset.StandardCharsets import java.time.LocalDateTime import java.time.ZoneOffset import java.util.concurrent.CompletableFuture import java.util.concurrent.ExecutionException import java.util.concurrent.TimeUnit import java.util.concurrent.TimeoutException import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder @SuppressWarnings("unused") class BE_Express_CreateOrder_SFTC implements BusinessExecutor { private final Logger logger = LogManager.getLogger(this.getClass().getSimpleName()) @Resource(name = "property.sftc.appId") long sfAppId @Resource(name = "property.sftc.appKey") String sfAppKey @Resource(name = "property.sftc.apiUrl") String sfApiUrl @Resource JsonConvert jsonConvert @Resource(name = "APP_HOME") private String appHome private String appid @Resource ERPLockDataService lockDataService @Resource OrderSearchService orderSearchService @Resource OrderStepService orderStepService @Resource StoreService storeService @Resource TunaService tunaService @Resource ESClient esClient @Resource SupplierInitService supplierService private OrderDao orderDao @Override String scriptName() { return "顺丰同城创建订单" } @Override ERPModule module() { return ERPModule.EXPRESS_API } @Override OperatorWait getAWait(InvokeCallParams source) { return OperatorWait.ASNYC } @Override boolean needToken(InvokeCallParams source) { return true } @Override void start(long supplierCode) { orderDao = tunaService.generate(OrderDao.class) } @Override RetResult checkExecute(InvokeCallParams source) { //检查订单信息 def jsonSlurper = new JsonSlurper() def invokeOrder = jsonSlurper.parseText(source.params) String orderId = invokeOrder["idOrder"] as String if (source.currentUser == null) { return RetResult. errorT().retinfo("请登录") } RetResult orderResult = orderSearchService.getBusinessOrder(Long.parseLong(orderId), source.currentUser, source.dataSourceId, source.supplierCode) if (!orderResult.isSuccess()) { return RetResult. errorT().retinfo("无效的订单信息") } BusinessOrder businessOrder = orderResult.result if (source.currentUser.userFrom == TokenUserFrom.PC_STORE_ADMIN.value) { if (businessOrder.idStore != source.currentUser.idBindOrg) { return RetResult. errorT().retinfo("无效的订单信息") } } StoreInfo storeInfo = storeService.getStoreInfo(businessOrder.idStore, source.supplierCode, false, false, true) StorePlatform storePlatform = storeInfo.platformList.find { StringUtils.equalsIgnoreCase("SFTC", it.platformCode) } if (storePlatform == null) { return RetResult. errorT().retinfo("商家未授权顺丰同城") } return RetResult. successT().result(source) } @Override RetResult beforeExecute(InvokeCallParams source) { //锁定下订单数据 def jsonSlurper = new JsonSlurper() def invokeOrder = jsonSlurper.parseText(source.params) String orderId = invokeOrder["idOrder"] as String if (lockDataService.hLockAdd(orderId, RedisKeys.KEY_ERP_WORKING_ORDER, source.supplierCode) > 1) { return RetResult. errorT().retinfo(orderId + "提交工作中,请稍后刷新即可,无需重复操作") } return RetResult. successT().result(source) } @Override void afterExecute(boolean executeError, InvokeCallParams source, InvokeCallResult dest) { //解锁订单数据 def jsonSlurper = new JsonSlurper() def invokeOrder = jsonSlurper.parseText(source.params) String orderId = invokeOrder["idOrder"] as String lockDataService.hLockDel(orderId, RedisKeys.KEY_ERP_WORKING_ORDER, source.supplierCode) } RetResult execute(InvokeCallParams source) { //检查订单信息 def jsonSlurper = new JsonSlurper() def invokeOrder = jsonSlurper.parseText(source.params) String orderId = invokeOrder["idOrder"] as String RetResult orderResult = orderSearchService.getBusinessOrder(Long.parseLong(orderId), source.currentUser, source.dataSourceId, source.supplierCode, ReadOrderOption.ORDER_FINANCES, ReadOrderOption.ORDER_DELIVERY, ReadOrderOption.ORDER_PRODUCT) if (!orderResult.isSuccess()) { return RetResult. errorT().retinfo("无效的订单信息") } BusinessOrder businessOrder = orderResult.result StoreInfo storeInfo = storeService.getStoreInfo(businessOrder.idStore, source.supplierCode, false, false, true) if (storeInfo == null) { return RetResult. errorT().retinfo("无效的门店信息") } StorePlatform storePlatform = storeInfo.platformList.find { StringUtils.equalsIgnoreCase("SFTC", it.platformCode) } if (storePlatform == null) { return RetResult. errorT().retinfo("商家未授权顺丰同城") } //秒级时间戳,groovy里面不让用system long currentTime = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)) long testTime = LocalDateTime.now().toInstant(ZoneOffset.ofHours(8)).toEpochMilli() def sfOrder = [ dev_id : sfAppId, shop_id : storePlatform.platformStoreId, shop_type : 1, shop_order_id : businessOrder.orderCode, order_source : businessOrder.incomePlatformName, order_sequence: String.valueOf(businessOrder.orderSequence), order_time : currentTime, push_time : currentTime, return_flag : 511, version : 19, order_detail : [ total_price : ERPUtils.money100(businessOrder.orderFinances.orderMoney), product_type : 1, weight_gram : 1L, product_num : businessOrder.detailItemList.sum { it.itemCount }, product_type_num: 1, product_detail : businessOrder.detailItemList.collect { detailItem -> def productDetail = [ product_name: detailItem.itemName, product_num : detailItem.itemCount ] return productDetail } ], receive : [ user_name : businessOrder.orderDeliveryInfo.receiveMan, user_phone : businessOrder.orderDeliveryInfo.contractPhone, user_lng : String.valueOf(businessOrder.orderDeliveryInfo.geoPoiLocation.longitude), user_lat : String.valueOf(businessOrder.orderDeliveryInfo.geoPoiLocation.latitude), user_address: businessOrder.orderDeliveryInfo.deliverAddress ] ] String postData = JSON.toJSONString(sfOrder) logger.info("请求数据: " + postData) String sign = ExpressApiSign.sfGenerateOpenSign(postData, sfAppId, sfAppKey) String url = sfApiUrl + "createorder?sign=" + sign CompletableFuture apiResult = HttpTools.postHttpContentAsync(url, 5000, StandardCharsets.UTF_8, postData, ["Content-Type": "application/json;charset=utf-8"]) try { String sfCreateOrderJson = apiResult.get(6000, TimeUnit.SECONDS) def sfOrderData = jsonSlurper.parseText(sfCreateOrderJson) //下单没有发送异步消息 logger.info(sfOrderData) if (sfOrderData["error_code"] == 0) { businessOrder.outGoingPlatformId = storePlatform.idPlatformInfo businessOrder.outGoingPlatformName = storePlatform.platformName businessOrder.outGoingPlatformOrderCode = sfOrderData["result"]["sf_order_id"] businessOrder.outGoingPlatformBillCode = sfOrderData["result"]["sf_bill_id"] businessOrder.orderFinances.expressTotalPrice = ERPUtils.money(sfOrderData["result"]["total_price"] as long) businessOrder.orderFinances.expressFreeSendServiceFee = ERPUtils.money(sfOrderData["result"]["free_send_service_fee"] as long) businessOrder.orderFinances.expressTotalPayMoney = ERPUtils.money(sfOrderData["result"]["total_pay_money"] as long) businessOrder.orderFinances.expressRealPayMoney = ERPUtils.money(sfOrderData["result"]["real_pay_money"] as long) businessOrder.orderFinances.expressCouponsTotalFee = ERPUtils.money(sfOrderData["result"]["coupons_total_fee"] as long) businessOrder.orderStatus = BusinessOrderStatus.delivery.value OrderStep expressStep = orderStepService.parseOrderStep(businessOrder.id, "配送发单", "[" + storePlatform.platformName + "]配送单号: " + businessOrder.outGoingPlatformOrderCode, source.currentUser) List stepList = new ArrayList<>() stepList << expressStep int iData = orderDao.expressCreateOrder(businessOrder, businessOrder.orderFinances, stepList, source.dataSourceId, source.supplierCode + "_1") if (iData >= 0) { BulkRequestBuilder bulkRequest = esClient.getClient().prepareBulk().setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) try { UpdateRequest orderRequest = new UpdateRequest( supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_DELIVER_BUSINESS_ORDER_INDEX, 1), ESKeys.ES_DELIVER_BUSINESS_ORDER_TYPE, String.valueOf(businessOrder.id)) .doc(jsonBuilder() .startObject() .field("outGoingPlatformId", businessOrder.outGoingPlatformId) .field("outGoingPlatformName", businessOrder.outGoingPlatformName) .field("outGoingPlatformOrderCode", businessOrder.outGoingPlatformOrderCode) .field("outGoingPlatformBillCode", businessOrder.outGoingPlatformBillCode) .field("orderStatus", businessOrder.orderStatus) .endObject()) bulkRequest.add(orderRequest) UpdateRequest orderFinanceRequest = new UpdateRequest( supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_DELIVER_BUSINESS_ORDER_INDEX, 1), ESKeys.ES_DELIVER_ORDER_FINANCES_TYPE, String.valueOf(businessOrder.orderFinances.id)) .parent(String.valueOf(businessOrder.id)) .doc(jsonBuilder() .startObject() .field("expressTotalPrice", businessOrder.orderFinances.expressTotalPrice) .field("expressFreeSendServiceFee", businessOrder.orderFinances.expressFreeSendServiceFee) .field("expressTotalPayMoney", businessOrder.orderFinances.expressTotalPayMoney) .field("expressRealPayMoney", businessOrder.orderFinances.expressRealPayMoney) .field("expressCouponsTotalFee", businessOrder.orderFinances.expressCouponsTotalFee) .endObject()) bulkRequest.add(orderFinanceRequest) stepList.each { orderStep -> IndexRequestBuilder orderStepRequest = esClient.getClient() .prepareIndex(supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_DELIVER_ORDER_STEP_INDEX, 1), ESKeys.ES_DELIVER_ORDER_STEP_TYPE) .setSource(jsonConvert.convertTo(orderStep), XContentType.JSON) bulkRequest.add(orderStepRequest) } //写入到es索引中 BulkResponse bulkResponse = bulkRequest.execute().actionGet() if (bulkResponse.hasFailures()) { logger.error("订单配送发单错误:" + bulkResponse.buildFailureMessage()) } } catch (Exception e) { logger.error("订单配送发单错误:" + e.getMessage(), e) } } return RetResult. successT().result( InvokeCallResult.success().data(JSON.toJSONString(sfOrderData)) ) } else { return RetResult. successT().result( InvokeCallResult.error(HttpCode.BAD_REQUEST.value(), sfOrderData["error_msg"] as String) ) } } catch (InterruptedException | ExecutionException | TimeoutException e) { logger.error(e.getMessage(), e) return RetResult. errorT().retinfo(e.getMessage()) } } }