BE_Express_PreCreateOrder_SFTC.groovy 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import com.alibaba.fastjson2.JSON
  2. import com.dderp.common.api.BusinessExecutor
  3. import com.dderp.common.api.ERPLockDataService
  4. import com.dderp.common.api.StoreService
  5. import com.dderp.common.api.flycat.OrderSearchService
  6. import com.dderp.common.datas.ERPModule
  7. import com.dderp.common.datas.ReadOrderOption
  8. import com.dderp.common.datas.TokenUserFrom
  9. import com.dderp.common.entity.base.InvokeCallParams
  10. import com.dderp.common.entity.base.InvokeCallResult
  11. import com.dderp.common.entity.order.BusinessOrder
  12. import com.dderp.common.entity.store.StoreInfo
  13. import com.dderp.common.entity.store.StorePlatform
  14. import com.dderp.common.http.HttpTools
  15. import com.dderp.common.tool.ERPUtils
  16. import com.dySweetFishPlugin.sql.dao.OperatorWait
  17. import com.sweetfish.convert.json.JsonConvert
  18. import com.sweetfish.service.RetResult
  19. import groovy.json.JsonSlurper
  20. import org.apache.commons.lang3.StringUtils
  21. import org.apache.logging.log4j.LogManager
  22. import org.apache.logging.log4j.Logger
  23. import org.rex.RMap
  24. import javax.annotation.Resource
  25. import java.nio.charset.StandardCharsets
  26. import java.time.LocalDateTime
  27. import java.time.ZoneOffset
  28. import java.util.concurrent.CompletableFuture
  29. import java.util.concurrent.ExecutionException
  30. import java.util.concurrent.TimeUnit
  31. import java.util.concurrent.TimeoutException
  32. @SuppressWarnings("unused")
  33. class BE_Express_PreCreateOrder_SFTC implements BusinessExecutor<InvokeCallParams, InvokeCallResult> {
  34. private final Logger logger = LogManager.getLogger(this.getClass().getSimpleName())
  35. @Resource(name = "property.sftc.appId")
  36. long sfAppId
  37. @Resource(name = "property.sftc.appKey")
  38. String sfAppKey
  39. @Resource(name = "property.sftc.apiUrl")
  40. String sfApiUrl
  41. @Resource
  42. JsonConvert jsonConvert
  43. @Resource
  44. ERPLockDataService lockDataService
  45. @Resource
  46. OrderSearchService orderSearchService
  47. @Resource
  48. StoreService storeService
  49. @Override
  50. String scriptName() {
  51. return "顺丰同城预创建订单--价格计算"
  52. }
  53. @Override
  54. ERPModule module() {
  55. return ERPModule.EXPRESS_API
  56. }
  57. @Override
  58. OperatorWait getAWait(InvokeCallParams source) {
  59. return OperatorWait.SYNC
  60. }
  61. @Override
  62. RetResult<InvokeCallParams> checkExecute(InvokeCallParams source) {
  63. //检查订单信息
  64. def jsonSlurper = new JsonSlurper()
  65. def invokeOrder = jsonSlurper.parseText(source.params)
  66. String idOrder = invokeOrder["idOrder"] as String
  67. if (source.currentUser == null) {
  68. return RetResult.<InvokeCallParams> errorT().retinfo("请登录")
  69. }
  70. RetResult<BusinessOrder> orderResult = orderSearchService.getBusinessOrder(Long.parseLong(idOrder), source.currentUser, source.dataSourceId, source.supplierCode)
  71. if (!orderResult.isSuccess()) {
  72. return RetResult.<InvokeCallParams> errorT().retinfo("无效的订单信息")
  73. }
  74. BusinessOrder businessOrder = orderResult.result
  75. if ((source.currentUser.userFrom == TokenUserFrom.APP_STORE_ADMIN.value) || (source.currentUser.userFrom == TokenUserFrom.PC_STORE_ADMIN.value)) {
  76. if (businessOrder.idStore != source.currentUser.idBindOrg) {
  77. return RetResult.<InvokeCallParams> errorT().retinfo("无效的订单信息")
  78. }
  79. }
  80. return RetResult.<InvokeCallParams> successT().result(source)
  81. }
  82. RetResult<InvokeCallResult> execute(InvokeCallParams source) {
  83. //预创建订单,并非真正发单;用来验证是否可以发单并在成功时返回时效、计价等信息,也可用来验证地址以及时间是否在顺丰的配送范围内
  84. def jsonSlurper = new JsonSlurper()
  85. def invokeOrder = jsonSlurper.parseText(source.params)
  86. String idOrder = invokeOrder["idOrder"] as String
  87. RetResult<BusinessOrder> orderResult = orderSearchService.getBusinessOrder(Long.parseLong(idOrder), source.currentUser, source.dataSourceId, source.supplierCode, ReadOrderOption.ORDER_FINANCES, ReadOrderOption.ORDER_DELIVERY)
  88. if (!orderResult.isSuccess()) {
  89. return RetResult.<InvokeCallResult> errorT().retinfo("无效的订单信息")
  90. }
  91. BusinessOrder businessOrder = orderResult.result
  92. StoreInfo storeInfo = storeService.getStoreInfo(businessOrder.idStore, source.supplierCode, false, false, true)
  93. StorePlatform storePlatform = storeInfo.platformList.find { StringUtils.equalsIgnoreCase("SFTC", it.platformCode) }
  94. if (storePlatform == null) {
  95. //统一返回,避免前端获取值不同
  96. def preDeliveryInfo = [
  97. errCode : 1001,
  98. errMsg : "商家未授权顺丰同城",
  99. //配送金额
  100. totalPrice : 0,
  101. //配送距离
  102. distanceMeter: 0
  103. ]
  104. return RetResult.<InvokeCallResult> successT().result(
  105. InvokeCallResult.success().data(JSON.toJSONString(preDeliveryInfo))
  106. )
  107. }
  108. //秒级时间戳,groovy里面不让用system
  109. long currentTime = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8))
  110. def sfOrder = [
  111. dev_id : sfAppId,
  112. shop_id : storePlatform.platformStoreId,
  113. product_type : 1,
  114. shop_type : 1,
  115. user_address : ERPUtils.convertNullToBlank(businessOrder.orderDeliveryInfo.deliverAddress),
  116. push_time : currentTime,
  117. return_flag : 511,
  118. multi_pickup_info: [
  119. [
  120. pickup_shop_address: storePlatform.platformShopAddress
  121. ]
  122. ]
  123. ]
  124. String postData = JSON.toJSONString(sfOrder)
  125. logger.info("请求数据: " + postData)
  126. String sign = ExpressApiSign.sfGenerateOpenSign(postData, sfAppId, sfAppKey)
  127. String url = sfApiUrl + "precreateorder?sign=" + sign
  128. CompletableFuture<String> apiResult = HttpTools.postHttpContentAsync(url,
  129. 5000,
  130. StandardCharsets.UTF_8,
  131. postData,
  132. ["Content-Type": "application/json;charset=utf-8"])
  133. try {
  134. String sfOrderResult = apiResult.get(6000, TimeUnit.SECONDS)
  135. def sfOrderJson = jsonSlurper.parseText(sfOrderResult)
  136. if (sfOrderJson["error_code"] == 0) {
  137. //统一返回,避免前端获取值不同
  138. def preDeliveryInfo = [
  139. errCode : 0,
  140. errMsg : "",
  141. //配送金额
  142. totalPrice : sfOrderJson["result"]["total_price"],
  143. //配送距离
  144. distanceMeter: sfOrderJson["result"]["delivery_distance_meter"]
  145. ]
  146. return RetResult.<InvokeCallResult> successT().result(
  147. InvokeCallResult.success().data(JSON.toJSONString(preDeliveryInfo))
  148. )
  149. } else {
  150. def preDeliveryInfo = [
  151. errCode : 1000,
  152. errMsg : sfOrderJson["error_msg"] as String,
  153. //配送金额
  154. totalPrice : 0,
  155. //配送距离
  156. distanceMeter: 0
  157. ]
  158. return RetResult.<InvokeCallResult> successT().result(
  159. InvokeCallResult.success().data(JSON.toJSONString(preDeliveryInfo))
  160. )
  161. }
  162. } catch (InterruptedException | ExecutionException | TimeoutException e) {
  163. logger.error(e.getMessage(), e)
  164. return RetResult.<InvokeCallResult> errorT().retinfo(e.getMessage())
  165. }
  166. }
  167. }