| Pass |
- 16:45:26 |
+ 15:45:08 |
Test passed
|
@@ -128,13 +128,13 @@
Started
-
七月 31, 2026 16:45:26
+
八月 05, 2026 15:45:07
Ended
-
七月 31, 2026 16:45:26
+
八月 05, 2026 15:45:08
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSeckillGroupController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSeckillGroupController.java
index b028169e..8037bd2a 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSeckillGroupController.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSeckillGroupController.java
@@ -3,12 +3,14 @@ package cc.hiver.mall.controller;
import cc.hiver.core.common.redis.RedisTemplateHelper;
import cc.hiver.core.common.utils.ResultUtil;
import cc.hiver.core.common.vo.Result;
+import cc.hiver.mall.entity.BaseDeliveryFeeSetting;
import cc.hiver.mall.entity.SeckillGroupCategory;
import cc.hiver.mall.entity.SeckillGroupProduct;
import cc.hiver.mall.pojo.dto.SeckillGroupProductDTO;
import cc.hiver.mall.pojo.dto.ShopCacheDTO;
import cc.hiver.mall.pojo.query.SeckillGroupProductQuery;
import cc.hiver.mall.pojo.vo.SeckillGroupProductVO;
+import cc.hiver.mall.service.mybatis.BaseDeliveryFeeSettingService;
import cc.hiver.mall.service.mybatis.SeckillGroupCategoryService;
import cc.hiver.mall.service.mybatis.SeckillGroupProductService;
import cn.hutool.json.JSONUtil;
@@ -22,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
+import java.math.BigDecimal;
import java.util.List;
@Slf4j
@@ -44,6 +47,9 @@ public class AdminSeckillGroupController {
@Autowired
private RedisTemplateHelper redisTemplateHelper;
+ @Autowired
+ private BaseDeliveryFeeSettingService baseDeliveryFeeSettingService;
+
@RequestMapping(value = "/deliveryTime/save", method = RequestMethod.POST)
@ApiOperation(value = "淇濆瓨鍖哄煙鎷煎洟閰嶉佹椂闀")
public Result saveDeliveryTime(@RequestBody DeliveryTimeSetting setting) {
@@ -82,6 +88,26 @@ public class AdminSeckillGroupController {
return new ResultUtil().setData(getCustomerPhoneByRegionId(redisTemplateHelper, regionId));
}
+ @RequestMapping(value = "/baseDeliveryFee/save", method = RequestMethod.POST)
+ @ApiOperation(value = "淇濆瓨鍖哄煙鍩虹閰嶉佽垂")
+ public Result saveBaseDeliveryFee(@RequestBody BaseDeliveryFeeSetting setting) {
+ if (setting == null || StringUtils.isBlank(setting.getRegionId())) {
+ return ResultUtil.error("鍖哄煙ID涓嶈兘涓虹┖");
+ }
+ if (!isValidBaseDeliveryFee(setting.getBaseDeliveryFee())) {
+ return ResultUtil.error("鍩虹閰嶉佽垂蹇呴』涓洪潪璐熼噾棰濓紝涓旀渶澶氫繚鐣2浣嶅皬鏁");
+ }
+ setting.setBaseDeliveryFee(setting.getBaseDeliveryFee().setScale(2));
+ baseDeliveryFeeSettingService.saveOrUpdateByRegionId(setting);
+ return ResultUtil.success("淇濆瓨鎴愬姛");
+ }
+
+ @RequestMapping(value = "/baseDeliveryFee/get", method = RequestMethod.GET)
+ @ApiOperation(value = "鏌ヨ鍖哄煙鍩虹閰嶉佽垂")
+ public Result getBaseDeliveryFee(@RequestParam(value = "regionId") String regionId) {
+ return new ResultUtil().setData(getBaseDeliveryFeeByRegionId(baseDeliveryFeeSettingService, regionId));
+ }
+
public static Integer getDeliveryTimeByRegionId(RedisTemplateHelper redisTemplateHelper, String regionId) {
if (redisTemplateHelper == null || StringUtils.isBlank(regionId)) {
return DEFAULT_GROUP_DELIVERY_TIME;
@@ -105,6 +131,20 @@ public class AdminSeckillGroupController {
return StringUtils.isBlank(value) ? "" : value;
}
+ public static BigDecimal getBaseDeliveryFeeByRegionId(BaseDeliveryFeeSettingService service, String regionId) {
+ if (service == null || StringUtils.isBlank(regionId)) {
+ return null;
+ }
+ return service.getFeeByRegionId(regionId);
+ }
+
+ private boolean isValidBaseDeliveryFee(BigDecimal amount) {
+ if (amount == null || amount.compareTo(BigDecimal.ZERO) < 0) {
+ return false;
+ }
+ return amount.stripTrailingZeros().scale() <= 2;
+ }
+
public static Integer getTotalDeliveryTimeByRegionIdAndShopId(RedisTemplateHelper redisTemplateHelper, String regionId, String shopId) {
return getShopCookingTimeByRegionIdAndShopId(redisTemplateHelper, regionId, shopId)
+ getDeliveryTimeByRegionId(redisTemplateHelper, regionId);
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ShopController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ShopController.java
index de1ea199..351432cd 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ShopController.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ShopController.java
@@ -59,6 +59,8 @@ import org.springframework.data.domain.PageImpl;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -73,6 +75,7 @@ import java.util.stream.Collectors;
public class ShopController {
private static final String GROUP_BUY_DEFAULT_PAGE_CACHE_PREFIX = "GROUP_BUY_DEFAULT_SHOP_PAGE:";
private static final long GROUP_BUY_DEFAULT_PAGE_CACHE_SECONDS = 5 * 60L;
+ private static final DateTimeFormatter BUSINESS_TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
@Autowired
private ShopService shopService;
@@ -419,19 +422,22 @@ public class ShopController {
});
}
- // 绋冲畾鎺掑簭锛氬悗鍙版煡璇㈠睍绀虹鐢ㄥ晢瀹讹紝浣嗙鐢ㄧ姸鎬佸缁堟斁鍦ㄦ渶鍚庛
- allShops.sort((s1, s2) -> {
- if (adminQuery) {
+ // 绋冲畾鎺掑簭锛氱敤鎴风浼樺厛灞曠ず钀ヤ笟涓殑鍟嗗锛屽悗鍙颁粛灏嗙鐢ㄥ晢瀹剁疆搴曘
+ if (adminQuery) {
+ allShops.sort((s1, s2) -> {
boolean disabled1 = ShopConstant.SHOP_STATUS_LOCK.equals(s1.getStatus());
boolean disabled2 = ShopConstant.SHOP_STATUS_LOCK.equals(s2.getStatus());
if (disabled1 != disabled2) {
return disabled1 ? 1 : -1;
}
- }
- Integer status1 = s1.getStatus() == null ? ShopConstant.SHOP_STATUS_LOCK : s1.getStatus();
- Integer status2 = s2.getStatus() == null ? ShopConstant.SHOP_STATUS_LOCK : s2.getStatus();
- return status1.compareTo(status2);
- });
+ Integer status1 = s1.getStatus() == null ? ShopConstant.SHOP_STATUS_LOCK : s1.getStatus();
+ Integer status2 = s2.getStatus() == null ? ShopConstant.SHOP_STATUS_LOCK : s2.getStatus();
+ return status1.compareTo(status2);
+ });
+ } else {
+ String currentBusinessTime = LocalTime.now().format(BUSINESS_TIME_FORMATTER);
+ allShops.sort((s1, s2) -> compareUserShopPriority(s1, s2, currentBusinessTime));
+ }
int pageNumber = pageVo.getPageNumber() > 0 ? pageVo.getPageNumber() : 1;
int pageSize = pageVo.getPageSize() > 0 ? pageVo.getPageSize() : 10;
@@ -561,6 +567,56 @@ public class ShopController {
return dto;
}
+ private int compareUserShopPriority(Shop s1, Shop s2, String currentTime) {
+ int compareResult = Integer.compare(getTakeawayStatusOrder(s1), getTakeawayStatusOrder(s2));
+ if (compareResult != 0) {
+ return compareResult;
+ }
+ compareResult = Integer.compare(getBusinessTimeOrder(s1, currentTime), getBusinessTimeOrder(s2, currentTime));
+ if (compareResult != 0) {
+ return compareResult;
+ }
+ Integer status1 = s1.getStatus() == null ? ShopConstant.SHOP_STATUS_LOCK : s1.getStatus();
+ Integer status2 = s2.getStatus() == null ? ShopConstant.SHOP_STATUS_LOCK : s2.getStatus();
+ return status1.compareTo(status2);
+ }
+
+ private int getTakeawayStatusOrder(Shop shop) {
+ ShopTakeaway takeaway = shop == null ? null : shop.getShopTakeaway();
+ Integer status = takeaway == null ? null : takeaway.getStatus();
+ return status == null ? 99 : status;
+ }
+
+ private int getBusinessTimeOrder(Shop shop, String currentTime) {
+ ShopTakeaway takeaway = shop == null ? null : shop.getShopTakeaway();
+ if (takeaway == null) {
+ return 1;
+ }
+ String begin = normalizeBusinessTime(takeaway.getBusinessHourBegin());
+ String end = normalizeBusinessTime(takeaway.getBusinessHourEnd());
+ if (CharSequenceUtil.isBlank(begin) || CharSequenceUtil.isBlank(end)) {
+ return 1;
+ }
+ if (begin.equals(end)) {
+ return 0;
+ }
+ boolean inBusinessTime;
+ if (begin.compareTo(end) <= 0) {
+ inBusinessTime = begin.compareTo(currentTime) <= 0 && end.compareTo(currentTime) >= 0;
+ } else {
+ inBusinessTime = begin.compareTo(currentTime) <= 0 || end.compareTo(currentTime) >= 0;
+ }
+ return inBusinessTime ? 0 : 1;
+ }
+
+ private String normalizeBusinessTime(String value) {
+ if (CharSequenceUtil.isBlank(value)) {
+ return "";
+ }
+ String time = value.trim();
+ return time.length() >= 5 ? time.substring(0, 5) : time;
+ }
+
private void logSlowShopListQuery(String source, long startTime, long totalElements, int pageSize, String regionId) {
long cost = System.currentTimeMillis() - startTime;
if (cost > 300) {
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WorkerController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WorkerController.java
index 33084d9e..696a4459 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WorkerController.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WorkerController.java
@@ -22,6 +22,7 @@ import cc.hiver.mall.pojo.vo.WorkerRedisVo;
import cc.hiver.mall.service.RechargeService;
import cc.hiver.mall.service.ShopAreaService;
import cc.hiver.mall.service.ShopService;
+import cc.hiver.mall.service.mybatis.BaseDeliveryFeeSettingService;
import cc.hiver.mall.service.mybatis.WorkerRelaPriceService;
import cc.hiver.mall.utils.WaitOrderCacheUtil;
import cc.hiver.mall.utils.WorkerOrderCacheUtil;
@@ -94,6 +95,9 @@ public class WorkerController {
@Autowired
private RedisTemplateHelper redisTemplateHelper;
+ @Autowired
+ private BaseDeliveryFeeSettingService baseDeliveryFeeSettingService;
+
@RequestMapping(value = "/getByCondition", method = RequestMethod.POST)
@ApiOperation(value = "澶氭潯浠跺垎椤佃幏鍙栬鍗曞垪琛")
public Result> getByCondition(@RequestBody WorkerQueryVO worker) {
@@ -144,7 +148,7 @@ public class WorkerController {
if(u.getIsChangeArea() != null && u.getIsChangeArea() == 0){
return new ResultUtil().setData(worker);
}else{
- u.setWorkerName(user.getNickname());
+ u.setWorkerName(user.getNickname() == null ? "鍗婂緞楠戝+" : user.getNickname());
u.setUserId(user.getId());
u.setAvgTime(BigDecimal.valueOf(25));
u.setMobile(user.getMobile());
@@ -565,10 +569,12 @@ public class WorkerController {
@ApiOperation(value = "鏌ヨ鍚勯鍫傚尯鍩熷湪绾块厤閫佸憳鏁伴噺")
public Result> getOnlineWorkerByArea(@RequestParam(value = "parentId")String parentId) {
String cacheKey = ONLINE_WORKER_AREA_COUNT_CACHE_PREFIX + parentId;
+ BigDecimal baseDeliveryFee = baseDeliveryFeeSettingService.getFeeByRegionId(parentId);
String cacheJson = redisTemplateHelper.get(cacheKey);
if (StrUtil.isNotBlank(cacheJson)) {
try {
List cacheList = JSONUtil.toList(cacheJson, WorkerAreaOnlineCountVO.class);
+ fillBaseDeliveryFee(cacheList, baseDeliveryFee);
return new ResultUtil>().setData(cacheList);
} catch (Exception e) {
redisTemplateHelper.delete(cacheKey);
@@ -610,16 +616,27 @@ public class WorkerController {
countVO.setAreaName(entry.getValue());
Set workers = areaWorkerMap.get(entry.getKey());
countVO.setOnlineWorkerCount(workers != null ? workers.size() : 0);
+ countVO.setBaseDeliveryFee(baseDeliveryFee);
result.add(countVO);
}
redisTemplateHelper.set(cacheKey, JSONUtil.toJsonStr(result), ONLINE_WORKER_AREA_COUNT_CACHE_SECONDS, TimeUnit.SECONDS);
return new ResultUtil>().setData(result);
}
List list = workerRelaPriceMapper.getOnlineWorkerCountByCanteenArea(parentId);
+ fillBaseDeliveryFee(list, baseDeliveryFee);
redisTemplateHelper.set(cacheKey, JSONUtil.toJsonStr(list), ONLINE_WORKER_AREA_COUNT_CACHE_SECONDS, TimeUnit.SECONDS);
return new ResultUtil>().setData(list);
}
+ private void fillBaseDeliveryFee(List list, BigDecimal baseDeliveryFee) {
+ if (list == null) {
+ return;
+ }
+ for (WorkerAreaOnlineCountVO item : list) {
+ item.setBaseDeliveryFee(baseDeliveryFee);
+ }
+ }
+
@RequestMapping(value = "/getByWorkerId", method = RequestMethod.GET)
@ApiOperation(value = "鏌ヨ閰嶉佸憳淇℃伅")
public Result getByWorkerId(@RequestParam(value = "workerId")String workerId) {
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/BaseDeliveryFeeSettingMapper.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/BaseDeliveryFeeSettingMapper.java
new file mode 100644
index 00000000..eb879d81
--- /dev/null
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/BaseDeliveryFeeSettingMapper.java
@@ -0,0 +1,9 @@
+package cc.hiver.mall.dao.mapper;
+
+import cc.hiver.mall.entity.BaseDeliveryFeeSetting;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface BaseDeliveryFeeSettingMapper extends BaseMapper {
+}
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/BaseDeliveryFeeSetting.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/BaseDeliveryFeeSetting.java
new file mode 100644
index 00000000..ea9def0b
--- /dev/null
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/BaseDeliveryFeeSetting.java
@@ -0,0 +1,33 @@
+package cc.hiver.mall.entity;
+
+import cc.hiver.core.base.HiverBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import java.math.BigDecimal;
+
+/**
+ * 鏍″尯鍩虹閰嶉佽垂閰嶇疆銆
+ */
+@Data
+@Entity
+@DynamicInsert
+@DynamicUpdate
+@Table(name = "t_base_delivery_fee_setting")
+@TableName("t_base_delivery_fee_setting")
+@ApiModel(value = "鏍″尯鍩虹閰嶉佽垂閰嶇疆")
+public class BaseDeliveryFeeSetting extends HiverBaseEntity {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "鏍″尯id")
+ private String regionId;
+
+ @ApiModelProperty(value = "鏈浣庨厤閫佽垂")
+ private BigDecimal baseDeliveryFee;
+}
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/WorkerAreaOnlineCountVO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/WorkerAreaOnlineCountVO.java
index ddfa8f1a..acb1f331 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/WorkerAreaOnlineCountVO.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/WorkerAreaOnlineCountVO.java
@@ -4,6 +4,8 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
+import java.math.BigDecimal;
+
/**
* 椋熷爞鍖哄煙鍦ㄧ嚎閰嶉佸憳鏁伴噺缁熻銆
*/
@@ -19,4 +21,7 @@ public class WorkerAreaOnlineCountVO {
@ApiModelProperty(value = "鍦ㄧ嚎閰嶉佸憳鏁伴噺")
private Integer onlineWorkerCount;
+
+ @ApiModelProperty(value = "褰撳墠鏍″尯鍩虹閰嶉佽垂")
+ private BigDecimal baseDeliveryFee;
}
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/BaseDeliveryFeeSettingService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/BaseDeliveryFeeSettingService.java
new file mode 100644
index 00000000..73fd6d6d
--- /dev/null
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/BaseDeliveryFeeSettingService.java
@@ -0,0 +1,15 @@
+package cc.hiver.mall.service.mybatis;
+
+import cc.hiver.mall.entity.BaseDeliveryFeeSetting;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.math.BigDecimal;
+
+public interface BaseDeliveryFeeSettingService extends IService {
+
+ BaseDeliveryFeeSetting getByRegionId(String regionId);
+
+ BigDecimal getFeeByRegionId(String regionId);
+
+ BaseDeliveryFeeSetting saveOrUpdateByRegionId(BaseDeliveryFeeSetting setting);
+}
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/ShopServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/ShopServiceImpl.java
index e9b5507b..bc5039f2 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/ShopServiceImpl.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/ShopServiceImpl.java
@@ -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() {
@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 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