| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519 |
- import com.dderp.common.api.BusinessExecutor
- import com.dderp.common.api.SupplierInitService
- import com.dderp.common.datas.ERPModule
- import com.dderp.common.datas.ESKeys
- import com.dderp.common.datas.ReadOrderOption
- import com.dderp.common.entity.base.ProcessSearchOptionsItem
- import com.dderp.common.entity.order.BusinessOrder
- import com.dderp.common.tool.ERPUtils
- import com.dderp.common.datas.ReadOrderOption
- import com.dySweetFishPlugin.elasticsearch.ESClient
- import com.dySweetFishPlugin.tool.lang.DateUtil
- import com.sweetfish.convert.json.JsonConvert
- import com.sweetfish.service.RetResult
- import org.apache.commons.lang3.StringUtils
- import org.apache.logging.log4j.LogManager
- import org.apache.logging.log4j.Logger
- import org.elasticsearch.action.search.SearchResponse
- import org.elasticsearch.index.query.BoolQueryBuilder
- import org.elasticsearch.index.query.Operator
- import org.elasticsearch.index.query.QueryBuilder
- import org.elasticsearch.index.query.QueryBuilders
- import org.elasticsearch.join.query.JoinQueryBuilders
- import org.elasticsearch.search.aggregations.AggregationBuilders
- import org.elasticsearch.search.aggregations.metrics.sum.InternalSum
- import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount
- import org.elasticsearch.search.sort.SortBuilders
- import org.elasticsearch.search.sort.SortOrder
- import org.rex.RMap
- import javax.annotation.Resource
- import java.math.RoundingMode
- import java.util.function.ToLongFunction
- @SuppressWarnings(["rawtypes"])
- class BE_ERP_BusinessOrder_Search implements BusinessExecutor<ProcessSearchOptionsItem<ReadOrderOption>, BusinessOrder> {
- protected final Logger logger = LogManager.getLogger(this.getClass().getSimpleName())
- @Resource
- SupplierInitService supplierService
- @Resource
- ESClient esClient
- @Resource
- JsonConvert jsonConvert
- @Override
- String scriptName() {
- return "ERP-外卖订单-查询"
- }
- @Override
- ERPModule module() {
- return ERPModule.ERP_ORDER_SEARCH
- }
- def <T> List<T> searchOrderChildInfoList(Class<T> clazz, String childESType, long[] idOrders, long supplierCode) {
- return ESList.<T> getESList()
- .esClient(esClient)
- .jsonConvert(jsonConvert)
- .clazz(clazz)
- .queryBuilder({
- //获取完成的数据情况
- return QueryBuilders.boolQuery()
- .must(QueryBuilders.typeQuery(childESType))
- .must(QueryBuilders.termsQuery("idOrder", ERPUtils.longArrayToStrArray(idOrders)))
- })
- .index(supplierService.getDateYearESIndex(supplierCode, ESKeys.ES_ERP_PRINT_ORDER_INDEX, 1))
- .executeNonePage()
- }
- def <T> Map<Long, List<T>> searchOrderChildInfoMap(Class<T> clazz, String childESType, long[] idOrders, long supplierCode, ToLongFunction<T> convertLong) {
- return ESMap.<T> getESMap()
- .srcIds(idOrders)
- .esClient(esClient)
- .jsonConvert(jsonConvert)
- .clazz(clazz)
- .queryBuilder({
- //获取完成的数据情况
- return QueryBuilders.boolQuery()
- .must(QueryBuilders.typeQuery(childESType))
- .must(QueryBuilders.termsQuery("idOrder", ERPUtils.longArrayToStrArray(idOrders)))
- })
- .convertLongExecutor(convertLong) //这里直接写{it.idOrder},只要所有的子类有这个值,groovy应该是可以的,只是看着难受,让调用接口传入转换方法
- .index(supplierService.getDateYearESIndex(supplierCode, ESKeys.ES_ERP_PRINT_ORDER_INDEX, 1))
- .execute()
- }
- def <T> List<T> getOrderChildInfo(Class<T> clazz, String childESType, long idOrder, long supplierCode) {
- return ESList.<T> getESList()
- .esClient(esClient)
- .jsonConvert(jsonConvert)
- .clazz(clazz)
- .queryBuilder({
- //获取完成的数据情况
- return QueryBuilders.boolQuery()
- .must(QueryBuilders.typeQuery(childESType))
- .must(QueryBuilders.termQuery("idOrder", idOrder))
- })
- .index(supplierService.getDateYearESIndex(supplierCode, ESKeys.ES_ERP_PRINT_ORDER_INDEX, 1))
- .executeNonePage()
- }
- def readOrderOptions(List<BusinessOrder> orderList, String dataSourceId, long supplierCode,
- ReadOrderOption... options) {
- long[] idOrders = orderList*.id.toArray() as long[]
- if ((options != null) && (options.length > 0) && (idOrders.length > 0)) {
- //防止搞坏事,options传重复数据过来,先去重
- options.toUnique().each { opt ->
- switch (opt) {
- }
- }
- }
- }
- def readOrderOptions(BusinessOrder businessOrder, String dataSourceId, long supplierCode,
- ReadOrderOption... options) {
- if ((options != null) && (options.length > 0)) {
- //防止搞坏事,options传重复数据过来,先去重
- options.toUnique().each { opt ->
- switch (opt) {
- }
- }
- }
- }
- def readOrderTotal(RMap searchData, String dataSourceId, long supplierCode, ReadOrderOption... options) {
- if (!(ReadOrderOption.ORDER_TOTAL in options)) {
- return null
- }
- //这里的查询需要和主表一致
- BoolQueryBuilder bqb = search(searchData)
- .byOrderStates()
- .byKeyWord()
- .byBeginTime_Create()
- .byEndTime_Create()
- .byClientName()
- .byIdClient()
- .byVoidFlag()
- .build()
- //合计金额,所以主表从orderMoney中开始
- SearchResponse searchResponse = esClient.getClient()
- .prepareSearch(supplierService.getDateYearESIndex(supplierCode, ESKeys.ES_ERP_PRINT_ORDER_INDEX, 1))
- .setQuery(bqb)
- .addAggregation(AggregationBuilders.count("sub_count").field("id"))
- .addAggregation(AggregationBuilders.sum("orderMoneyTotal_Sum").field("orderMoneyTotal"))
- .addAggregation(AggregationBuilders.sum("chargeMoney_Sum").field("chargeMoney"))
- .addAggregation(AggregationBuilders.sum("payMoney_Sum").field("payMoney"))
- .addAggregation(AggregationBuilders.sum("orderQty_Sum").field("orderQty"))
- .execute().actionGet()
- ValueCount orderCountSum = searchResponse.getAggregations().get("sub_count")
- InternalSum orderMoneyTotalSum = searchResponse.getAggregations().get("orderMoneyTotal_Sum")
- InternalSum chargeMoneySum = searchResponse.getAggregations().get("chargeMoney_Sum")
- InternalSum payMoneySum = searchResponse.getAggregations().get("payMoney_Sum")
- InternalSum orderQtySum = searchResponse.getAggregations().get("orderQty_Sum")
- RMap<String, Number> collectionData = new RMap<>()
- collectionData.put("orderCountSum", orderCountSum.getValue())
- collectionData.put("orderMoneyTotalSum", BigDecimal.valueOf(orderMoneyTotalSum.getValue()).setScale(2, RoundingMode.HALF_UP))
- collectionData.put("chargeMoneySum", BigDecimal.valueOf(chargeMoneySum.getValue()).setScale(2, RoundingMode.HALF_UP))
- collectionData.put("payMoneySum", BigDecimal.valueOf(payMoneySum.getValue()).setScale(2, RoundingMode.HALF_UP))
- collectionData.put("orderQtySum", BigDecimal.valueOf(orderQtySum.getValue()).setScale(0, RoundingMode.HALF_UP))
- return collectionData
- }
- private RetResult<List<BusinessOrder>> queryByConditions(ProcessSearchOptionsItem<ReadOrderOption> source) {
- String orderByField = "createTimeLong"
- String orderBySort = "desc"
- if (StringUtils.isNotBlank(source.orderBy)) {
- orderByField = source.orderBy.split(",")[0].trim()
- orderBySort = source.orderBy.split(",")[1].trim().toLowerCase()
- }
- List<BusinessOrder> orderList = ESList.<BusinessOrder> getESList()
- .esClient(esClient)
- .jsonConvert(jsonConvert)
- .clazz(BusinessOrder.class)
- .queryBuilder({
- return search(source.searchData)
- .byOrderStates()
- .byKeyWord()
- .byBeginTime_Create()
- .byEndTime_Create()
- .byClientName()
- .byIdClient()
- .byVoidFlag()
- .build()
- })
- .index(supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_ERP_PRINT_ORDER_INDEX, 1))
- .sortBuilder({
- switch (orderBySort) {
- case 'asc': return SortBuilders.fieldSort(orderByField).order(SortOrder.ASC)
- case 'desc': return SortBuilders.fieldSort(orderByField).order(SortOrder.DESC)
- }
- })
- .dataExecutor(null)
- .executePage(source.pageFlipper)
- readOrderOptions(orderList, source.dataSourceId, source.supplierCode, source.options)
- RMap<String, Number> collectionData = readOrderTotal(source.searchData, source.dataSourceId, source.supplierCode, source.options)
- return RetResult.<List<BusinessOrder>> successT().result(orderList).page(source.pageFlipper).attachRMap(collectionData)
- }
- private RetResult<List<BusinessOrder>> queryByIds(ProcessSearchOptionsItem<ReadOrderOption> source) {
- if (!ERPUtils.mapContainKey(source.searchData, ERPUtils.PARAM_SEARCH_IDS)) {
- return RetResult.<List<BusinessOrder>> errorT().retinfo("无效的ids参数")
- }
- String[] idOrders = source.searchData.get(ERPUtils.PARAM_SEARCH_IDS)
- //ES规定,addIds或者terms中的数据长度好像是1024个限制,这里为了安全,把list拆分一下
- //待测试下,collate分隔之后的类型,不行的话还是得List<List<String>>
- //测试后,结果是List<List<>>,不明白数组为什么转成List
- List<List<String>> idOrderArrayList = idOrders.collate(500)
- List<BusinessOrder> orderList = new ArrayList<>()
- idOrderArrayList.each { l ->
- List<BusinessOrder> subOrderList = ESList.<BusinessOrder> getESList()
- .esClient(esClient)
- .jsonConvert(jsonConvert)
- .clazz(BusinessOrder.class)
- .queryBuilder({
- return search(source.searchData)
- .byIdOrders(l.toArray(String[]::new))
- .build()
- })
- .index(supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_ERP_PRINT_ORDER_INDEX, 1))
- .executeNonePage()
- readOrderOptions(subOrderList, source.dataSourceId, source.supplierCode, source.options)
- if (!subOrderList.isEmpty()) {
- orderList.addAll(subOrderList)
- }
- }
- return RetResult.<List<BusinessOrder>> successT().result(orderList)
- }
- private RetResult<BusinessOrder> queryById(ProcessSearchOptionsItem<ReadOrderOption> source) {
- if (!ERPUtils.mapContainKey(source.searchData, ERPUtils.PARAM_SEARCH_ID)) {
- return RetResult.<BusinessOrder> errorT().retinfo("无效的id参数")
- }
- long idOrder = source.searchData.getLong(ERPUtils.PARAM_SEARCH_ID)
- BusinessOrder businessOrder = ESOne.<BusinessOrder> getESOneInfo()
- .esClient(esClient)
- .jsonConvert(jsonConvert)
- .clazz(BusinessOrder.class)
- .queryBuilder({
- //获取完成的数据情况
- ESConditionBuilder qb = search(null).byIdOrder(idOrder)
- //这里还需要判断数据权限
- return qb.build()
- })
- .index(supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_ERP_PRINT_ORDER_INDEX, 1))
- .execute()
- if (businessOrder == null) {
- return RetResult.<BusinessOrder> errorT().retinfo("无效的订单")
- }
- readOrderOptions(businessOrder, source.dataSourceId, source.supplierCode, source.options)
- return RetResult.<BusinessOrder> successT().result(businessOrder)
- }
- private RetResult<BusinessOrder> queryByCode(ProcessSearchOptionsItem<ReadOrderOption> source) {
- if (!ERPUtils.mapContainKey(source.searchData, ERPUtils.PARAM_SEARCH_CODE)) {
- return RetResult.<BusinessOrder> errorT().retinfo("无效的id参数")
- }
- String orderCode = source.searchData.getString(ERPUtils.PARAM_SEARCH_CODE)
- BusinessOrder businessOrder = ESOne.<BusinessOrder> getESOneInfo()
- .esClient(esClient)
- .jsonConvert(jsonConvert)
- .clazz(BusinessOrder.class)
- .queryBuilder({
- //获取完成的数据情况
- return search(null).byOrderCode(orderCode).build()
- })
- .index(supplierService.getDateYearESIndex(source.supplierCode, ESKeys.ES_ERP_PRINT_ORDER_INDEX, 1))
- .execute()
- if (businessOrder == null) {
- return RetResult.<BusinessOrder> errorT().retinfo("无效的订单")
- }
- readOrderOptions(businessOrder, source.dataSourceId, source.supplierCode, source.options)
- return RetResult.<BusinessOrder> successT().result(businessOrder)
- }
- @Override
- RetResult<BusinessOrder> execute(ProcessSearchOptionsItem<ReadOrderOption> source) {
- //可以参考一些都能运的代码,但那个硬编码需要多一些,这里直接判断搜索条件里面都有没有对应的条件
- if (ERPUtils.mapContainKey(source.searchData, ERPUtils.PARAM_SEARCH_ID)) {
- return queryById(source)
- } else if (ERPUtils.mapContainKey(source.searchData, ERPUtils.PARAM_SEARCH_CODE)) {
- return queryByCode(source)
- }
- return RetResult.<BusinessOrder> errorT().retinfo("无效的查询方式execute,查多数据应该使用executeList")
- }
- @Override
- RetResult<List<BusinessOrder>> executeList(ProcessSearchOptionsItem<ReadOrderOption> source) {
- if (ERPUtils.mapContainKey(source.searchData, ERPUtils.PARAM_SEARCH_IDS)) {
- return queryByIds(source)
- } else {
- return queryByConditions(source)
- }
- }
- //region 条件构造
- //groovy没法用java中类似SendOrderESConditionBuilder的静态方法构造内部类,强制编译不报错,运行还是报错无适配的构造函数,但用常规的类好使,估计是内部类有什么说法
- ESConditionBuilder search(RMap searchData) {
- return new ESConditionBuilder(searchData, QueryBuilders.boolQuery().must(QueryBuilders.typeQuery(ESKeys.ES_ERP_PRINT_ORDER_TYPE)))
- }
- //这里是做一个示例,表示通过查部件子表查询订单
- ESConditionBuilder searchByOrderRider(RMap searchData) {
- return new ESConditionBuilder(searchData, QueryBuilders.boolQuery().must(QueryBuilders.typeQuery(ESKeys.ES_ERP_ORDER_PART_TYPE)))
- }
- //endregion
- class ESConditionBuilder {
- RMap searchData
- BoolQueryBuilder qb
- ESConditionBuilder() {
- }
- ESConditionBuilder(RMap searchData) {
- this.searchData = searchData
- }
- ESConditionBuilder(RMap searchData, BoolQueryBuilder qb) {
- this.searchData = searchData
- this.qb = qb
- }
- //上面没法用java类似的静态方法返回条件,运行期还是报错没有适配的构造函数
- //注意这里如果定义成闭包,不能用this做流式写法,参考https://groovy-lang.org/closures.html#closure-owner
- //但是用了owner,返回的类型是Object,还得做转换,所以这里直接用java的写法
- ESConditionBuilder byIdOrders(String[] idOrders) {
- if (idOrders.length > 0) {
- qb = qb.must(QueryBuilders.idsQuery(ESKeys.ES_ERP_PRINT_ORDER_TYPE).addIds(idOrders))
- }
- return this
- }
- ESConditionBuilder byIdOrders(List<Long> idOrders) {
- if (!idOrders.isEmpty()) {
- qb = qb.must(QueryBuilders.idsQuery(ESKeys.ES_ERP_PRINT_ORDER_TYPE).addIds(ERPUtils.longArrayToStrArray(ERPUtils.longListToArray(idOrders))))
- }
- return this
- }
- ESConditionBuilder byIdOrder(long idOrder) {
- //这里不要判断idOrder是否大于0,防止条件漏了
- qb = qb.must(QueryBuilders.idsQuery(ESKeys.ES_ERP_PRINT_ORDER_TYPE).addIds(String.valueOf(idOrder)))
- return this
- }
- ESConditionBuilder byKeyWord() {
- if (ERPUtils.mapContainKey(searchData, "keyWord")) {
- String keyWord = searchData.getString("keyWord")
- QueryBuilder qbKeyWord = QueryBuilders.boolQuery()
- .should(QueryBuilders.termQuery("orderCode", keyWord.toLowerCase()))
- .should(QueryBuilders.matchQuery("orderName", keyWord).operator(Operator.AND))
- .should(QueryBuilders.matchQuery("clientName", keyWord).operator(Operator.AND))
- .should(QueryBuilders.matchQuery("productName", keyWord).operator(Operator.AND))
- .should(QueryBuilders.matchQuery("createMan", keyWord).operator(Operator.AND))
- .should(QueryBuilders.matchQuery("orderRegion", keyWord).operator(Operator.AND))
- qb = qb.must(qbKeyWord)
- }
- return this
- }
- ESConditionBuilder byOrderStates() {
- if (ERPUtils.mapContainKey(searchData, "orderStates")) {
- String orderStates = searchData.getString("orderStates")
- qb = qb.must(QueryBuilders.termsQuery("orderState", orderStates.split(",")))
- }
- return this
- }
- ESConditionBuilder byOrderStates(String orderStates) {
- qb = qb.must(QueryBuilders.termsQuery("orderState", orderStates.split(",")))
- return this
- }
- ESConditionBuilder byOrderState(int orderState) {
- qb = qb.must(QueryBuilders.termQuery("orderState", orderState))
- return this
- }
- ESConditionBuilder byVoidFlag() {
- if (ERPUtils.mapContainKey(searchData, "voidFlag")) {
- int voidFlag = searchData.getInt("voidFlag")
- if (voidFlag >= 0) {
- qb = qb.must(QueryBuilders.termQuery("voidFlag", voidFlag))
- }
- }
- return this
- }
- ESConditionBuilder byVoidFlag(int voidFlag) {
- if (voidFlag >= 0) {
- qb = qb.must(QueryBuilders.termQuery("voidFlag", voidFlag))
- }
- return this
- }
- ESConditionBuilder byOrderCode() {
- if (ERPUtils.mapContainKey(searchData, "orderCode")) {
- String orderCode = searchData.getString("orderCode")
- qb = qb.must(QueryBuilders.termQuery("orderCode", orderCode.toLowerCase()))
- }
- return this
- }
- ESConditionBuilder byOrderCode(String orderCode) {
- qb = qb.must(QueryBuilders.termQuery("orderCode", orderCode.toLowerCase()))
- return this
- }
- ESConditionBuilder byBeginTime_Create() {
- if (ERPUtils.mapContainKey(searchData, "beginTime")) {
- String beginTimeStr = searchData.getString("beginTime")
- long beginTime
- if (beginTimeStr.contains("-")) {
- beginTime = DateUtil.getStartOfDay(DateUtil.asDate(beginTimeStr, "yyyy-MM-dd")).getTime()
- } else {
- beginTime = DateUtil.getStartOfDay(new Date(searchData.getLong("beginTime"))).getTime()
- }
- qb = qb.must(QueryBuilders.rangeQuery("createTimeLong").gte(beginTime))
- }
- return this
- }
- ESConditionBuilder byEndTime_Create() {
- if (ERPUtils.mapContainKey(searchData, "endTime")) {
- String endTimeStr = searchData.getString("endTime")
- long endTime
- if (endTimeStr.contains("-")) {
- endTime = DateUtil.getEndOfDay(DateUtil.asDate(endTimeStr, "yyyy-MM-dd")).getTime()
- } else {
- endTime = DateUtil.getEndOfDay(new Date(searchData.getLong("endTime"))).getTime()
- }
- qb = qb.must(QueryBuilders.rangeQuery("createTimeLong").lte(endTime))
- }
- return this
- }
- ESConditionBuilder byClientName() {
- if (ERPUtils.mapContainKey(searchData, "clientName")) {
- String clientName = searchData.getString("clientName")
- qb = qb.must(QueryBuilders.boolQuery()
- .should(QueryBuilders.matchQuery("clientName", clientName).analyzer("index_ansj").operator(Operator.AND))
- .should(QueryBuilders.termQuery("clientName.number", clientName.toLowerCase()))
- .should(QueryBuilders.matchQuery("clientName.letter", clientName.toLowerCase()).operator(Operator.AND)))
- }
- return this
- }
- ESConditionBuilder byIdClient() {
- if (ERPUtils.mapContainKey(searchData, "idClient")) {
- long idClient = searchData.getLong("idClient")
- //这里不管是否大于0,都查询
- qb = qb.must(QueryBuilders.termQuery("idClient", idClient))
- }
- return this
- }
- ESConditionBuilder byIdClient(long idClient) {
- qb = qb.must(QueryBuilders.termQuery("idClient", idClient))
- return this
- }
- ESConditionBuilder byOrderParentQuery(QueryBuilder qbParent) {
- qb = qb.must(JoinQueryBuilders.hasParentQuery(ESKeys.ES_ERP_PRINT_ORDER_TYPE, qbParent, false))
- return this
- }
- BoolQueryBuilder build() {
- return qb
- }
- }
- }
|