BE_Express_CreateOrder_SFTC.groovy 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. import com.alibaba.fastjson2.JSON
  2. import com.dderp.business.dao.OrderDao
  3. import com.dderp.common.api.BusinessExecutor
  4. import com.dderp.common.api.ERPLockDataService
  5. import com.dderp.common.api.StoreService
  6. import com.dderp.common.api.SupplierInitService
  7. import com.dderp.common.api.flycat.OrderSearchService
  8. import com.dderp.common.api.flycat.OrderStepService
  9. import com.dderp.common.datas.*
  10. import com.dderp.common.datas.flycat.BusinessOrderStatus
  11. import com.dderp.common.entity.base.InvokeCallParams
  12. import com.dderp.common.entity.base.InvokeCallResult
  13. import com.dderp.common.entity.order.BusinessOrder
  14. import com.dderp.common.entity.order.OrderStep
  15. import com.dderp.common.entity.store.StoreInfo
  16. import com.dderp.common.entity.store.StorePlatform
  17. import com.dderp.common.http.HttpTools
  18. import com.dderp.common.tool.ERPUtils
  19. import com.dySweetFishPlugin.elasticsearch.ESClient
  20. import com.dySweetFishPlugin.sql.dao.OperatorWait
  21. import com.dySweetFishPlugin.sql.dao.TunaService
  22. import com.sweetfish.convert.json.JsonConvert
  23. import com.sweetfish.service.RetResult
  24. import groovy.json.JsonSlurper
  25. import org.apache.commons.lang3.StringUtils
  26. import org.apache.logging.log4j.LogManager
  27. import org.apache.logging.log4j.Logger
  28. import org.elasticsearch.action.bulk.BulkRequestBuilder
  29. import org.elasticsearch.action.bulk.BulkResponse
  30. import org.elasticsearch.action.index.IndexRequestBuilder
  31. import org.elasticsearch.action.support.WriteRequest
  32. import org.elasticsearch.action.update.UpdateRequest
  33. import org.elasticsearch.common.xcontent.XContentType
  34. import javax.annotation.Resource
  35. import java.nio.charset.StandardCharsets
  36. import java.time.LocalDateTime
  37. import java.time.ZoneOffset
  38. import java.util.concurrent.CompletableFuture
  39. import java.util.concurrent.ExecutionException
  40. import java.util.concurrent.TimeUnit
  41. import java.util.concurrent.TimeoutException
  42. import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder
  43. @SuppressWarnings("unused")
  44. class BE_Express_CreateOrder_SFTC implements BusinessExecutor<InvokeCallParams, InvokeCallResult> {
  45. private final Logger logger = LogManager.getLogger(this.getClass().getSimpleName())
  46. @Resource(name = "property.sftc.appId")
  47. long sfAppId
  48. @Resource(name = "property.sftc.appKey")
  49. String sfAppKey
  50. @Resource(name = "property.sftc.apiUrl")
  51. String sfApiUrl
  52. @Resource
  53. JsonConvert jsonConvert
  54. @Resource(name = "APP_HOME")
  55. private String appHome
  56. private String appid
  57. @Resource
  58. ERPLockDataService lockDataService
  59. @Resource
  60. OrderSearchService orderSearchService
  61. @Resource
  62. OrderStepService orderStepService
  63. @Resource
  64. StoreService storeService
  65. @Resource
  66. TunaService tunaService
  67. @Resource
  68. ESClient esClient
  69. @Resource
  70. SupplierInitService supplierService
  71. private OrderDao orderDao
  72. @Override
  73. String scriptName() {
  74. return "顺丰同城创建订单"
  75. }
  76. @Override
  77. ERPModule module() {
  78. return ERPModule.EXPRESS_API
  79. }
  80. @Override
  81. OperatorWait getAWait(InvokeCallParams source) {
  82. return OperatorWait.ASNYC
  83. }
  84. @Override
  85. boolean needToken(InvokeCallParams source) {
  86. return true
  87. }
  88. @Override
  89. void start(long supplierCode) {
  90. orderDao = tunaService.generate(OrderDao.class)
  91. }
  92. @Override
  93. RetResult<InvokeCallParams> checkExecute(InvokeCallParams source) {
  94. //检查订单信息
  95. def jsonSlurper = new JsonSlurper()
  96. def invokeOrder = jsonSlurper.parseText(source.params)
  97. String orderId = invokeOrder["idOrder"] as String
  98. if (source.currentUser == null) {
  99. return RetResult.<InvokeCallParams> errorT().retinfo("请登录")
  100. }
  101. RetResult<BusinessOrder> orderResult = orderSearchService.getBusinessOrder(Long.parseLong(orderId), source.currentUser, source.dataSourceId, source.supplierCode)
  102. if (!orderResult.isSuccess()) {
  103. return RetResult.<InvokeCallParams> errorT().retinfo("无效的订单信息")
  104. }
  105. BusinessOrder businessOrder = orderResult.result
  106. if ((source.currentUser.userFrom == TokenUserFrom.APP_STORE_ADMIN.value) || (source.currentUser.userFrom == TokenUserFrom.PC_STORE_ADMIN.value)) {
  107. if (businessOrder.idStore != source.currentUser.idBindOrg) {
  108. return RetResult.<InvokeCallParams> errorT().retinfo("无效的订单信息")
  109. }
  110. }
  111. StoreInfo storeInfo = storeService.getStoreInfo(businessOrder.idStore, source.supplierCode, false, false, true)
  112. StorePlatform storePlatform = storeInfo.platformList.find { StringUtils.equalsIgnoreCase("SFTC", it.platformCode) }
  113. if (storePlatform == null) {
  114. return RetResult.<InvokeCallParams> errorT().retinfo("商家未授权顺丰同城")
  115. }
  116. return RetResult.<InvokeCallParams> successT().result(source)
  117. }
  118. @Override
  119. RetResult<InvokeCallParams> beforeExecute(InvokeCallParams source) {
  120. //锁定下订单数据
  121. def jsonSlurper = new JsonSlurper()
  122. def invokeOrder = jsonSlurper.parseText(source.params)
  123. String orderId = invokeOrder["idOrder"] as String
  124. if (lockDataService.hLockAdd(orderId, RedisKeys.KEY_ERP_WORKING_ORDER, source.supplierCode) > 1) {
  125. return RetResult.<InvokeCallParams> errorT().retinfo(orderId + "提交工作中,请稍后刷新即可,无需重复操作")
  126. }
  127. return RetResult.<InvokeCallParams> successT().result(source)
  128. }
  129. @Override
  130. void afterExecute(boolean executeError, InvokeCallParams source, InvokeCallResult dest) {
  131. //解锁订单数据
  132. def jsonSlurper = new JsonSlurper()
  133. def invokeOrder = jsonSlurper.parseText(source.params)
  134. String orderId = invokeOrder["idOrder"] as String
  135. lockDataService.hLockDel(orderId, RedisKeys.KEY_ERP_WORKING_ORDER, source.supplierCode)
  136. }
  137. RetResult<InvokeCallResult> execute(InvokeCallParams source) {
  138. //检查订单信息
  139. def jsonSlurper = new JsonSlurper()
  140. def invokeOrder = jsonSlurper.parseText(source.params)
  141. String orderId = invokeOrder["idOrder"] as String
  142. RetResult<BusinessOrder> orderResult = orderSearchService.getBusinessOrder(Long.parseLong(orderId),
  143. source.currentUser, source.dataSourceId, source.supplierCode,
  144. ReadOrderOption.ORDER_FINANCES, ReadOrderOption.ORDER_DELIVERY, ReadOrderOption.ORDER_PRODUCT)
  145. if (!orderResult.isSuccess()) {
  146. return RetResult.<InvokeCallResult> errorT().retinfo("无效的订单信息")
  147. }
  148. BusinessOrder businessOrder = orderResult.result
  149. StoreInfo storeInfo = storeService.getStoreInfo(businessOrder.idStore, source.supplierCode, false, false, true)
  150. if (storeInfo == null) {
  151. return RetResult.<InvokeCallResult> errorT().retinfo("无效的门店信息")
  152. }
  153. StorePlatform storePlatform = storeInfo.platformList.find { StringUtils.equalsIgnoreCase("SFTC", it.platformCode) }
  154. if (storePlatform == null) {
  155. return RetResult.<InvokeCallResult> errorT().retinfo("商家未授权顺丰同城")
  156. }
  157. //秒级时间戳,groovy里面不让用system
  158. long currentTime = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8))
  159. long testTime = LocalDateTime.now().toInstant(ZoneOffset.ofHours(8)).toEpochMilli()
  160. def sfOrder = [
  161. dev_id : sfAppId,
  162. shop_id : storePlatform.platformStoreId,
  163. shop_type : 1,
  164. shop_order_id : 'S' + String.valueOf(businessOrder.id), //这里只能用字符串,不能用全数字
  165. order_source : businessOrder.incomePlatformName,
  166. order_sequence: String.valueOf(businessOrder.orderSequence),
  167. order_time : currentTime,
  168. push_time : currentTime,
  169. return_flag : 511,
  170. version : 19,
  171. order_detail : [
  172. total_price : ERPUtils.money100(businessOrder.orderFinances.orderMoney),
  173. product_type : 1,
  174. weight_gram : 1L,
  175. product_num : businessOrder.detailItemList.sum { it.itemCount },
  176. product_type_num: 1,
  177. product_detail : businessOrder.detailItemList.collect { detailItem ->
  178. def productDetail = [
  179. product_name: detailItem.itemName,
  180. product_num : detailItem.itemCount
  181. ]
  182. return productDetail
  183. }
  184. ],
  185. receive : [
  186. user_name : businessOrder.orderDeliveryInfo.receiveMan,
  187. user_phone : businessOrder.orderDeliveryInfo.contractPhone,
  188. user_lng : String.valueOf(businessOrder.orderDeliveryInfo.geoPoiLocation.longitude),
  189. user_lat : String.valueOf(businessOrder.orderDeliveryInfo.geoPoiLocation.latitude),
  190. user_address: businessOrder.orderDeliveryInfo.deliverAddress
  191. ]
  192. ]
  193. String postData = JSON.toJSONString(sfOrder)
  194. logger.info("请求数据: " + postData)
  195. String sign = ExpressApiSign.sfGenerateOpenSign(postData, sfAppId, sfAppKey)
  196. String url = sfApiUrl + "createorder?sign=" + sign
  197. CompletableFuture<String> apiResult = HttpTools.postHttpContentAsync(url,
  198. 5000,
  199. StandardCharsets.UTF_8,
  200. postData,
  201. ["Content-Type": "application/json;charset=utf-8"])
  202. try {
  203. String sfCreateOrderJson = apiResult.get(6000, TimeUnit.SECONDS)
  204. def sfOrderData = jsonSlurper.parseText(sfCreateOrderJson)
  205. //下单没有发送异步消息
  206. logger.info(sfOrderData)
  207. if (sfOrderData["error_code"] == 0) {
  208. businessOrder.outGoingPlatformId = storePlatform.idPlatformInfo
  209. businessOrder.outGoingPlatformName = storePlatform.platformName
  210. businessOrder.outGoingPlatformOrderCode = sfOrderData["result"]["sf_order_id"]
  211. businessOrder.outGoingPlatformBillCode = sfOrderData["result"]["sf_bill_id"]
  212. businessOrder.orderFinances.expressTotalPrice = ERPUtils.money(sfOrderData["result"]["total_price"] as long)
  213. if (sfOrderData["result"]["free_send_service_fee"] != null) {
  214. //省心送费,单位分。在顺丰同城后台配置,配置后有此字段和费用。
  215. businessOrder.orderFinances.expressFreeSendServiceFee = ERPUtils.money(sfOrderData["result"]["free_send_service_fee"] as long)
  216. } else {
  217. businessOrder.orderFinances.expressFreeSendServiceFee = BigDecimal.ZERO
  218. }
  219. businessOrder.orderFinances.expressTotalPayMoney = ERPUtils.money(sfOrderData["result"]["total_pay_money"] as long)
  220. businessOrder.orderFinances.expressRealPayMoney = ERPUtils.money(sfOrderData["result"]["real_pay_money"] as long)
  221. businessOrder.orderFinances.expressCouponsTotalFee = ERPUtils.money(sfOrderData["result"]["coupons_total_fee"] as long)
  222. businessOrder.orderStatus = BusinessOrderStatus.delivery.value
  223. OrderStep expressStep = orderStepService.parseOrderStep(businessOrder.id,
  224. "配送发单",
  225. "[" + storePlatform.platformName + "]配送单号: " + businessOrder.outGoingPlatformOrderCode,
  226. source.currentUser)
  227. List<OrderStep> stepList = new ArrayList<>()
  228. stepList << expressStep
  229. int iData = orderDao.expressCreateOrder(businessOrder, businessOrder.orderFinances, stepList, source.dataSourceId, source.supplierCode + "_1")
  230. if (iData >= 0) {
  231. BulkRequestBuilder bulkRequest = esClient.getClient().prepareBulk().setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
  232. try {
  233. UpdateRequest orderRequest = new UpdateRequest(
  234. supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_DELIVER_BUSINESS_ORDER_INDEX, 1),
  235. ESKeys.ES_DELIVER_BUSINESS_ORDER_TYPE, String.valueOf(businessOrder.id))
  236. .doc(jsonBuilder()
  237. .startObject()
  238. .field("outGoingPlatformId", businessOrder.outGoingPlatformId)
  239. .field("outGoingPlatformName", businessOrder.outGoingPlatformName)
  240. .field("outGoingPlatformOrderCode", businessOrder.outGoingPlatformOrderCode)
  241. .field("outGoingPlatformBillCode", businessOrder.outGoingPlatformBillCode)
  242. .field("orderStatus", businessOrder.orderStatus)
  243. .endObject())
  244. bulkRequest.add(orderRequest)
  245. UpdateRequest orderFinanceRequest = new UpdateRequest(
  246. supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_DELIVER_BUSINESS_ORDER_INDEX, 1),
  247. ESKeys.ES_DELIVER_ORDER_FINANCES_TYPE, String.valueOf(businessOrder.orderFinances.id))
  248. .parent(String.valueOf(businessOrder.id))
  249. .doc(jsonBuilder()
  250. .startObject()
  251. .field("expressTotalPrice", businessOrder.orderFinances.expressTotalPrice)
  252. .field("expressFreeSendServiceFee", businessOrder.orderFinances.expressFreeSendServiceFee)
  253. .field("expressTotalPayMoney", businessOrder.orderFinances.expressTotalPayMoney)
  254. .field("expressRealPayMoney", businessOrder.orderFinances.expressRealPayMoney)
  255. .field("expressCouponsTotalFee", businessOrder.orderFinances.expressCouponsTotalFee)
  256. .endObject())
  257. bulkRequest.add(orderFinanceRequest)
  258. stepList.each { orderStep ->
  259. IndexRequestBuilder orderStepRequest = esClient.getClient()
  260. .prepareIndex(supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_DELIVER_ORDER_STEP_INDEX, 1),
  261. ESKeys.ES_DELIVER_ORDER_STEP_TYPE)
  262. .setSource(jsonConvert.convertTo(orderStep), XContentType.JSON)
  263. bulkRequest.add(orderStepRequest)
  264. }
  265. //写入到es索引中
  266. BulkResponse bulkResponse = bulkRequest.execute().actionGet()
  267. if (bulkResponse.hasFailures()) {
  268. logger.error("订单配送发单错误:" + bulkResponse.buildFailureMessage())
  269. }
  270. } catch (Exception e) {
  271. logger.error("订单配送发单错误:" + e.getMessage(), e)
  272. }
  273. }
  274. return RetResult.<InvokeCallResult> successT().result(
  275. InvokeCallResult.success().data(JSON.toJSONString(sfOrderData))
  276. )
  277. } else {
  278. return RetResult.<InvokeCallResult> successT().result(
  279. InvokeCallResult.error(HttpCode.BAD_REQUEST.value(), sfOrderData["error_msg"] as String)
  280. )
  281. }
  282. } catch (InterruptedException | ExecutionException | TimeoutException e) {
  283. logger.error(e.getMessage(), e)
  284. return RetResult.<InvokeCallResult> errorT().retinfo(e.getMessage())
  285. }
  286. }
  287. }