BE_ERP_OrderRefundRequest_Search.groovy 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. import com.dderp.common.api.BusinessExecutor
  2. import com.dderp.common.api.SupplierInitService
  3. import com.dderp.common.datas.ERPModule
  4. import com.dderp.common.datas.ESKeys
  5. import com.dderp.common.datas.ReadOrderOption
  6. import com.dderp.common.entity.base.ProcessSearchOptionsItem
  7. import com.dderp.common.entity.order.OrderRefundRequest
  8. import com.dderp.common.tool.ERPUtils
  9. import com.dySweetFishPlugin.elasticsearch.ESClient
  10. import com.dySweetFishPlugin.tool.lang.DateUtil
  11. import com.sweetfish.convert.json.JsonConvert
  12. import com.sweetfish.service.RetResult
  13. import org.apache.commons.lang3.StringUtils
  14. import org.apache.logging.log4j.LogManager
  15. import org.apache.logging.log4j.Logger
  16. import org.elasticsearch.action.search.SearchResponse
  17. import org.elasticsearch.index.query.BoolQueryBuilder
  18. import org.elasticsearch.index.query.Operator
  19. import org.elasticsearch.index.query.QueryBuilder
  20. import org.elasticsearch.index.query.QueryBuilders
  21. import org.elasticsearch.join.query.JoinQueryBuilders
  22. import org.elasticsearch.search.aggregations.AggregationBuilders
  23. import org.elasticsearch.search.aggregations.metrics.sum.InternalSum
  24. import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount
  25. import org.elasticsearch.search.sort.SortBuilders
  26. import org.elasticsearch.search.sort.SortOrder
  27. import org.rex.RMap
  28. import javax.annotation.Resource
  29. import java.math.RoundingMode
  30. @SuppressWarnings(["rawtypes"])
  31. class BE_ERP_OrderRefundRequest_Search implements BusinessExecutor<ProcessSearchOptionsItem<ReadOrderOption>, OrderRefundRequest> {
  32. protected final Logger logger = LogManager.getLogger(this.getClass().getSimpleName())
  33. @Resource
  34. SupplierInitService supplierService
  35. @Resource
  36. ESClient esClient
  37. @Resource
  38. JsonConvert jsonConvert
  39. @Override
  40. String scriptName() {
  41. return "ERP-订单退款申请-查询"
  42. }
  43. @Override
  44. ERPModule module() {
  45. return ERPModule.ERP_ORDER_SEARCH
  46. }
  47. def readOrderOptions(List<OrderRefundRequest> requestList, String dataSourceId, long supplierCode,
  48. ReadOrderOption... options) {
  49. long[] idOrders = requestList*.id.toArray() as long[]
  50. if ((options != null) && (options.length > 0) && (idOrders.length > 0)) {
  51. //防止搞坏事,options传重复数据过来,先去重
  52. options.toUnique().each { opt ->
  53. switch (opt) {
  54. }
  55. }
  56. }
  57. }
  58. def readOrderOptions(OrderRefundRequest refundRequest, String dataSourceId, long supplierCode,
  59. ReadOrderOption... options) {
  60. if ((options != null) && (options.length > 0)) {
  61. //防止搞坏事,options传重复数据过来,先去重
  62. options.toUnique().each { opt ->
  63. switch (opt) {
  64. }
  65. }
  66. }
  67. }
  68. def readOrderTotal(RMap searchData, String dataSourceId, long supplierCode, ReadOrderOption... options) {
  69. if (!(ReadOrderOption.ORDER_TOTAL in options)) {
  70. return null
  71. }
  72. //这里的查询需要和主表一致
  73. BoolQueryBuilder bqb = search(searchData)
  74. .byRequestStatus()
  75. .byKeyWord()
  76. .byRequestStatus()
  77. .byOrderCode()
  78. .byBeginTime_Create()
  79. .byEndTime_Create()
  80. .byIdOrder()
  81. .byIdStore()
  82. .byIdStorePlatform()
  83. .byPlatformCode()
  84. .byPlatformType()
  85. .byOutAfterSaleId()
  86. .build()
  87. //合计金额,所以主表从orderMoney中开始
  88. SearchResponse searchResponse = esClient.getClient()
  89. .prepareSearch(supplierService.getDateYearESIndex(supplierCode, ESKeys.ES_DELIVER_BUSINESS_ORDER_INDEX, 1))
  90. .setQuery(bqb)
  91. .addAggregation(AggregationBuilders.count("sub_count").field("id"))
  92. .addAggregation(AggregationBuilders.sum("deliveryFee_Sum").field("deliveryFee"))
  93. .addAggregation(AggregationBuilders.sum("refundFee_Sum").field("refundFee"))
  94. .addAggregation(AggregationBuilders.sum("refundProdCount_Sum").field("refundProdCount"))
  95. .execute().actionGet()
  96. ValueCount requestCountSum = searchResponse.getAggregations().get("sub_count")
  97. InternalSum deliveryFeeSum = searchResponse.getAggregations().get("deliveryFee_Sum")
  98. InternalSum refundFeeSum = searchResponse.getAggregations().get("refundFee_Sum")
  99. InternalSum refundProdCountSum = searchResponse.getAggregations().get("refundProdCount_Sum")
  100. RMap<String, Number> collectionData = new RMap<>()
  101. collectionData.put("requestCountSum", requestCountSum.getValue())
  102. collectionData.put("deliveryFeeSum", BigDecimal.valueOf(deliveryFeeSum.getValue()).setScale(2, RoundingMode.HALF_UP))
  103. collectionData.put("refundFeeSum", BigDecimal.valueOf(refundFeeSum.getValue()).setScale(2, RoundingMode.HALF_UP))
  104. collectionData.put("refundProdCountSum", BigDecimal.valueOf(refundProdCountSum.getValue()).setScale(2, RoundingMode.HALF_UP))
  105. return collectionData
  106. }
  107. private RetResult<List<OrderRefundRequest>> queryByConditions(ProcessSearchOptionsItem<ReadOrderOption> source) {
  108. String orderByField = "createTimeLong"
  109. String orderBySort = "desc"
  110. if (StringUtils.isNotBlank(source.orderBy)) {
  111. orderByField = source.orderBy.split(",")[0].trim()
  112. orderBySort = source.orderBy.split(",")[1].trim().toLowerCase()
  113. }
  114. List<OrderRefundRequest> orderList = ESList.<OrderRefundRequest> getESList()
  115. .esClient(esClient)
  116. .jsonConvert(jsonConvert)
  117. .clazz(OrderRefundRequest.class)
  118. .queryBuilder({
  119. return search(source.searchData)
  120. .byRequestStatus()
  121. .byKeyWord()
  122. .byRequestStatus()
  123. .byOrderCode()
  124. .byBeginTime_Create()
  125. .byEndTime_Create()
  126. .byIdOrder()
  127. .byIdStore()
  128. .byIdStorePlatform()
  129. .byPlatformCode()
  130. .byPlatformType()
  131. .byOutAfterSaleId()
  132. .build()
  133. })
  134. .index(supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_DELIVER_ORDER_REFUND_REQUEST_INDEX, 1))
  135. .sortBuilder({
  136. switch (orderBySort) {
  137. case 'asc': return SortBuilders.fieldSort(orderByField).order(SortOrder.ASC)
  138. case 'desc': return SortBuilders.fieldSort(orderByField).order(SortOrder.DESC)
  139. }
  140. })
  141. .dataExecutor(null)
  142. .executePage(source.pageFlipper)
  143. readOrderOptions(orderList, source.dataSourceId, source.supplierCode, source.options)
  144. RMap<String, Number> collectionData = readOrderTotal(source.searchData, source.dataSourceId, source.supplierCode, source.options)
  145. return RetResult.<List<OrderRefundRequest>> successT().result(orderList).page(source.pageFlipper).attachRMap(collectionData)
  146. }
  147. private RetResult<List<OrderRefundRequest>> queryByIds(ProcessSearchOptionsItem<ReadOrderOption> source) {
  148. if (!ERPUtils.mapContainKey(source.searchData, ERPUtils.PARAM_SEARCH_IDS)) {
  149. return RetResult.<List<OrderRefundRequest>> errorT().retinfo("无效的ids参数")
  150. }
  151. String[] idOrders = source.searchData.get(ERPUtils.PARAM_SEARCH_IDS)
  152. //ES规定,addIds或者terms中的数据长度好像是1024个限制,这里为了安全,把list拆分一下
  153. //待测试下,collate分隔之后的类型,不行的话还是得List<List<String>>
  154. //测试后,结果是List<List<>>,不明白数组为什么转成List
  155. List<List<String>> idOrderArrayList = idOrders.collate(500)
  156. List<OrderRefundRequest> orderList = new ArrayList<>()
  157. idOrderArrayList.each { l ->
  158. List<OrderRefundRequest> subOrderList = ESList.<OrderRefundRequest> getESList()
  159. .esClient(esClient)
  160. .jsonConvert(jsonConvert)
  161. .clazz(OrderRefundRequest.class)
  162. .queryBuilder({
  163. return search(source.searchData)
  164. .byIds(l.toArray(String[]::new))
  165. .build()
  166. })
  167. .index(supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_DELIVER_ORDER_REFUND_REQUEST_INDEX, 1))
  168. .executeNonePage()
  169. readOrderOptions(subOrderList, source.dataSourceId, source.supplierCode, source.options)
  170. if (!subOrderList.isEmpty()) {
  171. orderList.addAll(subOrderList)
  172. }
  173. }
  174. return RetResult.<List<OrderRefundRequest>> successT().result(orderList)
  175. }
  176. private RetResult<OrderRefundRequest> queryById(ProcessSearchOptionsItem<ReadOrderOption> source) {
  177. if (!ERPUtils.mapContainKey(source.searchData, ERPUtils.PARAM_SEARCH_ID)) {
  178. return RetResult.<OrderRefundRequest> errorT().retinfo("无效的id参数")
  179. }
  180. long idOrder = source.searchData.getLong(ERPUtils.PARAM_SEARCH_ID)
  181. OrderRefundRequest businessOrder = ESOne.<OrderRefundRequest> getESOneInfo()
  182. .esClient(esClient)
  183. .jsonConvert(jsonConvert)
  184. .clazz(OrderRefundRequest.class)
  185. .queryBuilder({
  186. //获取完成的数据情况
  187. ESConditionBuilder qb = search(null).byId(idOrder)
  188. //这里还需要判断数据权限
  189. return qb.build()
  190. })
  191. .index(supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_DELIVER_ORDER_REFUND_REQUEST_INDEX, 1))
  192. .execute()
  193. if (businessOrder == null) {
  194. return RetResult.<OrderRefundRequest> errorT().retinfo("无效的订单")
  195. }
  196. readOrderOptions(businessOrder, source.dataSourceId, source.supplierCode, source.options)
  197. return RetResult.<OrderRefundRequest> successT().result(businessOrder)
  198. }
  199. private RetResult<OrderRefundRequest> queryByCode(ProcessSearchOptionsItem<ReadOrderOption> source) {
  200. if (!ERPUtils.mapContainKey(source.searchData, ERPUtils.PARAM_SEARCH_CODE)) {
  201. return RetResult.<OrderRefundRequest> errorT().retinfo("无效的id参数")
  202. }
  203. String orderCode = source.searchData.getString(ERPUtils.PARAM_SEARCH_CODE)
  204. OrderRefundRequest businessOrder = ESOne.<OrderRefundRequest> getESOneInfo()
  205. .esClient(esClient)
  206. .jsonConvert(jsonConvert)
  207. .clazz(OrderRefundRequest.class)
  208. .queryBuilder({
  209. //获取完成的数据情况
  210. return search(null).byOrderCode(orderCode).build()
  211. })
  212. .index(supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_DELIVER_ORDER_REFUND_REQUEST_INDEX, 1))
  213. .execute()
  214. if (businessOrder == null) {
  215. return RetResult.<OrderRefundRequest> errorT().retinfo("无效的订单")
  216. }
  217. readOrderOptions(businessOrder, source.dataSourceId, source.supplierCode, source.options)
  218. return RetResult.<OrderRefundRequest> successT().result(businessOrder)
  219. }
  220. @Override
  221. RetResult<OrderRefundRequest> execute(ProcessSearchOptionsItem<ReadOrderOption> source) {
  222. //可以参考一些都能运的代码,但那个硬编码需要多一些,这里直接判断搜索条件里面都有没有对应的条件
  223. if (ERPUtils.mapContainKey(source.searchData, ERPUtils.PARAM_SEARCH_ID)) {
  224. return queryById(source)
  225. } else if (ERPUtils.mapContainKey(source.searchData, ERPUtils.PARAM_SEARCH_CODE)) {
  226. return queryByCode(source)
  227. }
  228. return RetResult.<OrderRefundRequest> errorT().retinfo("无效的查询方式execute,查多数据应该使用executeList")
  229. }
  230. @Override
  231. RetResult<List<OrderRefundRequest>> executeList(ProcessSearchOptionsItem<ReadOrderOption> source) {
  232. if (ERPUtils.mapContainKey(source.searchData, ERPUtils.PARAM_SEARCH_IDS)) {
  233. return queryByIds(source)
  234. } else {
  235. return queryByConditions(source)
  236. }
  237. }
  238. //region 条件构造
  239. //groovy没法用java中类似SendOrderESConditionBuilder的静态方法构造内部类,强制编译不报错,运行还是报错无适配的构造函数,但用常规的类好使,估计是内部类有什么说法
  240. ESConditionBuilder search(RMap searchData) {
  241. return new ESConditionBuilder(searchData, QueryBuilders.boolQuery().must(QueryBuilders.typeQuery(ESKeys.ES_DELIVER_ORDER_REFUND_REQUEST_TYPE)))
  242. }
  243. //这里是做一个示例,表示通过查部件子表查询订单
  244. ESConditionBuilder searchByOrderRider(RMap searchData) {
  245. return new ESConditionBuilder(searchData, QueryBuilders.boolQuery().must(QueryBuilders.typeQuery(ESKeys.ES_ERP_ORDER_PART_TYPE)))
  246. }
  247. //endregion
  248. class ESConditionBuilder {
  249. RMap searchData
  250. BoolQueryBuilder qb
  251. ESConditionBuilder() {
  252. }
  253. ESConditionBuilder(RMap searchData) {
  254. this.searchData = searchData
  255. }
  256. ESConditionBuilder(RMap searchData, BoolQueryBuilder qb) {
  257. this.searchData = searchData
  258. this.qb = qb
  259. }
  260. //上面没法用java类似的静态方法返回条件,运行期还是报错没有适配的构造函数
  261. //注意这里如果定义成闭包,不能用this做流式写法,参考https://groovy-lang.org/closures.html#closure-owner
  262. //但是用了owner,返回的类型是Object,还得做转换,所以这里直接用java的写法
  263. ESConditionBuilder byIds(String[] ids) {
  264. if (ids.length > 0) {
  265. qb = qb.must(QueryBuilders.idsQuery(ESKeys.ES_DELIVER_ORDER_REFUND_REQUEST_TYPE).addIds(ids))
  266. }
  267. return this
  268. }
  269. ESConditionBuilder byIds(List<Long> ids) {
  270. if (!ids.isEmpty()) {
  271. qb = qb.must(QueryBuilders.idsQuery(ESKeys.ES_DELIVER_ORDER_REFUND_REQUEST_TYPE).addIds(ERPUtils.longArrayToStrArray(ERPUtils.longListToArray(ids))))
  272. }
  273. return this
  274. }
  275. ESConditionBuilder byId(long id) {
  276. //这里不要判断idOrder是否大于0,防止条件漏了
  277. qb = qb.must(QueryBuilders.idsQuery(ESKeys.ES_DELIVER_ORDER_REFUND_REQUEST_TYPE).addIds(String.valueOf(id)))
  278. return this
  279. }
  280. ESConditionBuilder byKeyWord() {
  281. if (ERPUtils.mapContainKey(searchData, "keyWord")) {
  282. String keyWord = searchData.getString("keyWord")
  283. QueryBuilder qbKeyWord = QueryBuilders.boolQuery()
  284. .should(QueryBuilders.termQuery("orderCode", keyWord.toLowerCase()))
  285. .should(QueryBuilders.matchQuery("orderName", keyWord).operator(Operator.AND))
  286. qb = qb.must(qbKeyWord)
  287. }
  288. return this
  289. }
  290. ESConditionBuilder byRequestStatus() {
  291. if (ERPUtils.mapContainKey(searchData, "requestStatus")) {
  292. String orderStates = searchData.getString("requestStatus")
  293. qb = qb.must(QueryBuilders.termsQuery("requestStatus", orderStates.split(",")))
  294. }
  295. return this
  296. }
  297. ESConditionBuilder byRequestStatus(String requestStatus) {
  298. qb = qb.must(QueryBuilders.termsQuery("requestStatus", requestStatus.split(",")))
  299. return this
  300. }
  301. ESConditionBuilder byRequestStatus(int requestStatus) {
  302. qb = qb.must(QueryBuilders.termQuery("requestStatus", requestStatus))
  303. return this
  304. }
  305. ESConditionBuilder byOrderCode() {
  306. if (ERPUtils.mapContainKey(searchData, "orderCode")) {
  307. String orderCode = searchData.getString("orderCode")
  308. qb = qb.must(QueryBuilders.termQuery("orderCode", orderCode.toLowerCase()))
  309. }
  310. return this
  311. }
  312. ESConditionBuilder byOrderCode(String orderCode) {
  313. qb = qb.must(QueryBuilders.termQuery("orderCode", orderCode.toLowerCase()))
  314. return this
  315. }
  316. ESConditionBuilder byBeginTime_Create() {
  317. if (ERPUtils.mapContainKey(searchData, "beginTime")) {
  318. String beginTimeStr = searchData.getString("beginTime")
  319. long beginTime
  320. if (beginTimeStr.contains("-")) {
  321. beginTime = DateUtil.getStartOfDay(DateUtil.asDate(beginTimeStr, "yyyy-MM-dd")).getTime()
  322. } else {
  323. beginTime = DateUtil.getStartOfDay(new Date(searchData.getLong("beginTime"))).getTime()
  324. }
  325. qb = qb.must(QueryBuilders.rangeQuery("createTimeLong").gte(beginTime))
  326. }
  327. return this
  328. }
  329. ESConditionBuilder byEndTime_Create() {
  330. if (ERPUtils.mapContainKey(searchData, "endTime")) {
  331. String endTimeStr = searchData.getString("endTime")
  332. long endTime
  333. if (endTimeStr.contains("-")) {
  334. endTime = DateUtil.getEndOfDay(DateUtil.asDate(endTimeStr, "yyyy-MM-dd")).getTime()
  335. } else {
  336. endTime = DateUtil.getEndOfDay(new Date(searchData.getLong("endTime"))).getTime()
  337. }
  338. qb = qb.must(QueryBuilders.rangeQuery("createTimeLong").lte(endTime))
  339. }
  340. return this
  341. }
  342. ESConditionBuilder byIdOrder() {
  343. if (ERPUtils.mapContainKey(searchData, "idOrder")) {
  344. long idOrder = searchData.getLong("idOrder")
  345. //这里不管是否大于0,都查询
  346. qb = qb.must(QueryBuilders.termQuery("idOrder", idOrder))
  347. }
  348. return this
  349. }
  350. ESConditionBuilder byIdStore() {
  351. if (ERPUtils.mapContainKey(searchData, "idStore")) {
  352. long idStore = searchData.getLong("idStore")
  353. //这里不管是否大于0,都查询
  354. qb = qb.must(QueryBuilders.termQuery("idStore", idStore))
  355. }
  356. return this
  357. }
  358. ESConditionBuilder byIdStorePlatform() {
  359. if (ERPUtils.mapContainKey(searchData, "idStorePlatform")) {
  360. long idStorePlatform = searchData.getLong("idStorePlatform")
  361. //这里不管是否大于0,都查询
  362. qb = qb.must(QueryBuilders.termQuery("idStorePlatform", idStorePlatform))
  363. }
  364. return this
  365. }
  366. ESConditionBuilder byPlatformCode() {
  367. if (ERPUtils.mapContainKey(searchData, "platformCode")) {
  368. String platformCode = searchData.getString("platformCode")
  369. qb = qb.must(QueryBuilders.termQuery("platformCode", platformCode.toLowerCase()))
  370. }
  371. return this
  372. }
  373. ESConditionBuilder byPlatformType() {
  374. if (ERPUtils.mapContainKey(searchData, "platformType")) {
  375. long platformType = searchData.getLong("platformType")
  376. //这里不管是否大于0,都查询
  377. qb = qb.must(QueryBuilders.termQuery("platformType", platformType))
  378. }
  379. return this
  380. }
  381. ESConditionBuilder byOutAfterSaleId() {
  382. if (ERPUtils.mapContainKey(searchData, "outAfterSaleId")) {
  383. String outAfterSaleId = searchData.getString("outAfterSaleId")
  384. qb = qb.must(QueryBuilders.termQuery("outAfterSaleId", outAfterSaleId.toLowerCase()))
  385. }
  386. return this
  387. }
  388. BoolQueryBuilder build() {
  389. return qb
  390. }
  391. }
  392. }