|
|
|
@ -56,6 +56,8 @@ import org.springframework.transaction.annotation.Transactional; |
|
|
|
|
|
|
|
import javax.persistence.criteria.*; |
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.time.LocalTime; |
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.List; |
|
|
|
@ -69,6 +71,7 @@ import java.util.Map; |
|
|
|
@Transactional |
|
|
|
public class ShopServiceImpl implements ShopService { |
|
|
|
private static final String GROUP_BUY_DEFAULT_PAGE_CACHE_PREFIX = "GROUP_BUY_DEFAULT_SHOP_PAGE:"; |
|
|
|
private static final DateTimeFormatter BUSINESS_TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm"); |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private ShopDao shopDao; |
|
|
|
@ -115,9 +118,9 @@ public class ShopServiceImpl implements ShopService { |
|
|
|
if (adminQuery) { |
|
|
|
pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.unsorted()); |
|
|
|
} else { |
|
|
|
Sort newSort = Sort.by(Sort.Direction.ASC, "status").and(pageSort); |
|
|
|
pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), newSort); |
|
|
|
pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.unsorted()); |
|
|
|
} |
|
|
|
String currentBusinessTime = LocalTime.now().format(BUSINESS_TIME_FORMATTER); |
|
|
|
return shopDao.findAll(new Specification<Shop>() { |
|
|
|
@Nullable |
|
|
|
@Override |
|
|
|
@ -196,12 +199,81 @@ public class ShopServiceImpl implements ShopService { |
|
|
|
orderList.add(order.isAscending() ? cb.asc(sortField) : cb.desc(sortField)); |
|
|
|
} |
|
|
|
cq.orderBy(orderList); |
|
|
|
} else if (!isCountQuery(cq)) { |
|
|
|
List<Order> orderList = new ArrayList<>(); |
|
|
|
orderList.add(cb.asc(buildTakeawayStatusOrder(root, cq, cb))); |
|
|
|
orderList.add(cb.asc(buildBusinessTimeOrder(root, cq, cb, currentBusinessTime))); |
|
|
|
orderList.add(cb.asc(statusField)); |
|
|
|
for (Sort.Order order : pageSort) { |
|
|
|
if ("status".equals(order.getProperty())) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
Path<Object> sortField = root.get(order.getProperty()); |
|
|
|
orderList.add(order.isAscending() ? cb.asc(sortField) : cb.desc(sortField)); |
|
|
|
} |
|
|
|
cq.orderBy(orderList); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
}, pageable); |
|
|
|
} |
|
|
|
|
|
|
|
private boolean isCountQuery(CriteriaQuery<?> cq) { |
|
|
|
Class<?> resultType = cq.getResultType(); |
|
|
|
return Long.class.equals(resultType) || long.class.equals(resultType); |
|
|
|
} |
|
|
|
|
|
|
|
private Expression<Integer> buildTakeawayStatusOrder(Root<Shop> root, CriteriaQuery<?> cq, CriteriaBuilder cb) { |
|
|
|
Subquery<Integer> statusQuery = cq.subquery(Integer.class); |
|
|
|
Root<ShopTakeaway> takeawayRoot = statusQuery.from(ShopTakeaway.class); |
|
|
|
statusQuery.select(cb.min(takeawayRoot.<Integer>get("status"))); |
|
|
|
statusQuery.where(cb.equal(takeawayRoot.get("shopId"), root.get("id"))); |
|
|
|
return cb.<Integer>selectCase() |
|
|
|
.when(cb.isNull(statusQuery), 99) |
|
|
|
.otherwise(statusQuery); |
|
|
|
} |
|
|
|
|
|
|
|
private Expression<Integer> buildBusinessTimeOrder(Root<Shop> root, CriteriaQuery<?> cq, CriteriaBuilder cb, String currentTime) { |
|
|
|
Subquery<String> beginQuery = buildTakeawayStringSubquery(root, cq, cb, "businessHourBegin"); |
|
|
|
Subquery<String> endQuery = buildTakeawayStringSubquery(root, cq, cb, "businessHourEnd"); |
|
|
|
Expression<String> now = cb.literal(currentTime); |
|
|
|
Expression<Boolean> missingTime = cb.or( |
|
|
|
cb.isNull(beginQuery), |
|
|
|
cb.isNull(endQuery), |
|
|
|
cb.equal(beginQuery, ""), |
|
|
|
cb.equal(endQuery, "") |
|
|
|
); |
|
|
|
Expression<Boolean> sameDayRange = cb.lessThanOrEqualTo(beginQuery, endQuery); |
|
|
|
Expression<Boolean> allDayRange = cb.equal(beginQuery, endQuery); |
|
|
|
Expression<Boolean> inSameDayRange = cb.and( |
|
|
|
cb.lessThanOrEqualTo(beginQuery, now), |
|
|
|
cb.greaterThanOrEqualTo(endQuery, now) |
|
|
|
); |
|
|
|
Expression<Boolean> inOvernightRange = cb.or( |
|
|
|
cb.lessThanOrEqualTo(beginQuery, now), |
|
|
|
cb.greaterThanOrEqualTo(endQuery, now) |
|
|
|
); |
|
|
|
Expression<Integer> sameDayResult = cb.<Integer>selectCase() |
|
|
|
.when(inSameDayRange, 0) |
|
|
|
.otherwise(1); |
|
|
|
Expression<Integer> overnightResult = cb.<Integer>selectCase() |
|
|
|
.when(inOvernightRange, 0) |
|
|
|
.otherwise(1); |
|
|
|
return cb.<Integer>selectCase() |
|
|
|
.when(missingTime, 1) |
|
|
|
.when(allDayRange, 0) |
|
|
|
.when(sameDayRange, sameDayResult) |
|
|
|
.otherwise(overnightResult); |
|
|
|
} |
|
|
|
|
|
|
|
private Subquery<String> buildTakeawayStringSubquery(Root<Shop> root, CriteriaQuery<?> cq, CriteriaBuilder cb, String fieldName) { |
|
|
|
Subquery<String> subquery = cq.subquery(String.class); |
|
|
|
Root<ShopTakeaway> takeawayRoot = subquery.from(ShopTakeaway.class); |
|
|
|
subquery.select(cb.least(takeawayRoot.<String>get(fieldName))); |
|
|
|
subquery.where(cb.equal(takeawayRoot.get("shopId"), root.get("id"))); |
|
|
|
return subquery; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public Shop findByShopName(String ShopName) { |
|
|
|
return shopDao.findByShopName(ShopName); |
|
|
|
|