Browse Source

对接拼团数据1

master
wangfukang 1 hour ago
parent
commit
6bac4905db
  1. 22
      hiver-admin/src/main/resources/application.yml
  2. 16
      hiver-admin/test-output/test-report.html
  3. 8
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallOrderController.java
  4. 9
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ProductCategoryController.java
  5. 209
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ShopController.java
  6. 42
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/ShopServiceImpl.java
  7. 20
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/DaQuReceiptRenderUtil.java

22
hiver-admin/src/main/resources/application.yml

@ -29,6 +29,12 @@ ie:
server:
port: 8888
# 响应 gzip 压缩 店铺列表这类大 JSON 字段名高度重复 压缩率约 6-8 倍 小程序端会自动解压
compression:
enabled: true
mime-types: application/json,application/xml,text/html,text/xml,text/plain,text/css,text/javascript,application/javascript
# 小于该阈值的响应不压缩 避免小响应白付 CPU
min-response-size: 2KB
servlet:
context-path: /
tomcat:
@ -50,7 +56,7 @@ spring:
# 数据源
datasource:
# url: jdbc:mysql://154.8.162.157:3306/hiver_shop?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&allowMultiQueries=true
url: jdbc:mysql://8.140.253.224:3306/school?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false&maxReconnects=10
url: jdbc:mysql://127.0.0.1:3306/school?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false&maxReconnects=10
username: root
# Jasypt加密 可到common-utils中找到JasyptUtil加解密工具类生成加密结果 格式为ENC(加密结果) 以下解密结果为123456
password: ENC(87YloapnWG6mLejOa27eLN0afFhCrbAGxoHXXrSUrGJ0trM/BndC2kx/gfoJsXIi)
@ -58,8 +64,16 @@ spring:
driver-class-name: com.mysql.jdbc.Driver
# Druid StatViewServlet配置
druid:
test-on-borrow: true
initial-size: 5
min-idle: 5
max-active: 30
max-wait: 3000
validation-query: SELECT 1
test-on-borrow: false
test-while-idle: true
test-on-return: false
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
stat-view-servlet:
# 默认true 内置监控页面首页/druid/index.html
enabled: true
@ -94,7 +108,7 @@ spring:
# Redis 若设有密码自行添加配置password
redis:
# host: 154.8.162.157
host: 8.140.253.224
host: 127.0.0.1
password: reddoor168
# 数据库索引 默认0
database: 1
@ -120,7 +134,7 @@ spring:
uris: http://localhost:9200
# RabbitMQ配置
rabbitmq:
host: 8.140.253.224
host: 127.0.0.1
port: 5672
username: root
password: ziyi123QQ

16
hiver-admin/test-output/test-report.html

@ -35,7 +35,7 @@
<a href="#"><span class="badge badge-primary">Hiver</span></a>
</li>
<li class="m-r-10">
<a href="#"><span class="badge badge-primary">九月 20, 2026 17:27:21</span></a>
<a href="#"><span class="badge badge-primary">九月 21, 2026 15:37:23</span></a>
</li>
</ul>
</div>
@ -84,7 +84,7 @@
<div class="test-detail">
<span class="meta text-white badge badge-sm"></span>
<p class="name">passTest</p>
<p class="text-sm"><span>17:27:22 下午</span> / <span>0.025 secs</span></p>
<p class="text-sm"><span>15:37:24 下午</span> / <span>0.022 secs</span></p>
</div>
<div class="test-contents d-none">
<div class="detail-head">
@ -92,9 +92,9 @@
<div class="info">
<div class='float-right'><span class='badge badge-default'>#test-id=1</span></div>
<h5 class="test-status text-pass">passTest</h5>
<span class='badge badge-success'>09.20.2026 17:27:22</span>
<span class='badge badge-danger'>09.20.2026 17:27:22</span>
<span class='badge badge-default'>0.025 secs</span>
<span class='badge badge-success'>09.21.2026 15:37:24</span>
<span class='badge badge-danger'>09.21.2026 15:37:24</span>
<span class='badge badge-default'>0.022 secs</span>
</div>
<div class="m-t-10 m-l-5"></div>
</div>
@ -104,7 +104,7 @@
<tbody>
<tr class="event-row">
<td><span class="badge log pass-bg">Pass</span></td>
<td>17:27:22</td>
<td>15:37:24</td>
<td>
Test passed
</td>
@ -128,13 +128,13 @@
<div class="col-md-3">
<div class="card"><div class="card-body">
<p class="m-b-0">Started</p>
<h3>九月 20, 2026 17:27:21</h3>
<h3>九月 21, 2026 15:37:23</h3>
</div></div>
</div>
<div class="col-md-3">
<div class="card"><div class="card-body">
<p class="m-b-0">Ended</p>
<h3>九月 20, 2026 17:27:22</h3>
<h3>九月 21, 2026 15:37:24</h3>
</div></div>
</div>
<div class="col-md-3">

8
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallOrderController.java

@ -165,7 +165,8 @@ public class MallOrderController {
@PostMapping("/cloudPrint/{id}")
@ApiOperation("手动云打印订单小票")
public Result<Object> cloudPrint(@ApiParam("订单ID") @PathVariable String id) {
public Result<Object> cloudPrint(@ApiParam("订单ID") @PathVariable String id,
@RequestParam(value = "scanVerify", required = false) Boolean scanVerify) {
MallOrderVO vo = mallOrderService.getOrderDetail(id);
if (vo == null) {
return ResultUtil.error("订单不存在");
@ -173,7 +174,10 @@ public class MallOrderController {
if (!daQuCloudPrintService.isCloudPrintShop(vo.getShopId())) {
return ResultUtil.error("当前商家未配置云打印");
}
orderAsyncProducer.sendCloudPrint(id, "MANUAL-" + System.currentTimeMillis());
String printReason = Boolean.TRUE.equals(scanVerify)
? "SCAN_VERIFY-" + System.currentTimeMillis()
: "MANUAL-" + System.currentTimeMillis();
orderAsyncProducer.sendCloudPrint(id, printReason);
return ResultUtil.success("云打印任务已发送");
}

9
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ProductCategoryController.java

@ -5,8 +5,10 @@ import cc.hiver.core.common.utils.ResultUtil;
import cc.hiver.core.common.utils.SecurityUtil;
import cc.hiver.core.common.vo.Result;
import cc.hiver.mall.entity.ProductCategory;
import cc.hiver.mall.entity.Shop;
import cc.hiver.mall.pojo.vo.ProductCategoryVo;
import cc.hiver.mall.pojo.vo.ProductCategoryVo2;
import cc.hiver.mall.service.ShopService;
import cc.hiver.mall.service.mybatis.ProductCategoryService;
import cc.hiver.mall.service.mybatis.ProductService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@ -37,6 +39,9 @@ public class ProductCategoryController {
@Autowired
private ProductService productService;
@Autowired
private ShopService shopService;
@Autowired
private SecurityUtil securityUtil;
@ -84,6 +89,10 @@ public class ProductCategoryController {
// 将该分类下的商品id删除掉
productService.deleteProductByCategoryId(productCategory.getId());
productCategoryService.removeProductCategoryCache(old.getShopId(), old.getId());
Shop shop = shopService.get(old.getShopId());
if (shop != null) {
shopService.refreshShopCache(shop.getId(), shop.getRegionId());
}
return ResultUtil.success("删除成功");
}

209
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ShopController.java

@ -79,6 +79,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 = 30L;
private static final long SHOP_LIST_SLOW_THRESHOLD_MS = 10L;
private static final DateTimeFormatter BUSINESS_TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
private static final String PRINTING_METHOD_BLUETOOTH = "bluetooth";
private static final String PRINTING_METHOD_CLOUD = "cloud";
@ -458,7 +459,7 @@ public class ShopController {
@ApiOperation("多条件分页获取公司列表")
public Result<Page<Shop>> getByCondition(Shop shop,
PageVo pageVo) {
long queryStartTime = System.currentTimeMillis();
ShopListStageTimer timer = new ShopListStageTimer();
String regionId = shop.getRegionId();
boolean adminQuery = CharSequenceUtil.isNotBlank(shop.getShopIcon());
boolean hasKeyword = hasSearchKeyword(shop);
@ -466,17 +467,23 @@ public class ShopController {
&& !hasKeyword
&& CharSequenceUtil.isBlank(shop.getShopName());
String defaultPageCacheKey = buildDefaultGroupBuyPageCacheKey(shop, pageVo, adminQuery);
timer.note("pageCacheKey", defaultPageCacheKey == null ? "null" : defaultPageCacheKey);
if (CharSequenceUtil.isNotBlank(defaultPageCacheKey)) {
String cacheJson = redisTemplateHelper.get(defaultPageCacheKey);
timer.mark("pageCacheGet");
timer.note("pageCacheBytes", cacheJson == null ? 0 : cacheJson.length());
if (CharSequenceUtil.isNotBlank(cacheJson)) {
try {
ShopListPageCache cache = JSONUtil.toBean(cacheJson, ShopListPageCache.class);
timer.mark("pageCacheParse");
if (cache != null && cache.getContent() != null) {
if (containsUserHiddenShop(cache.getContent())) {
redisTemplateHelper.delete(defaultPageCacheKey);
} else {
fillBaseDeliveryFee(cache.getContent(), regionId);
timer.mark("baseFee");
Page<Shop> pageResult = new PageImpl<>(cache.getContent(), PageUtil.initPage(pageVo), cache.getTotalElements());
logShopListQuery("pageCache", timer, cache.getTotalElements(), cache.getContent().size(), regionId);
return new ResultUtil<Page<Shop>>().setData(pageResult);
}
}
@ -488,10 +495,14 @@ public class ShopController {
}
if (useRegionCache) {
List<Object> values = redisTemplateHelper.hValues("SHOP_CACHE:" + regionId);
timer.mark("hvals");
if (values != null && !values.isEmpty()) {
List<Shop> allShops = new ArrayList<>();
long hvalsBytes = 0L;
for (Object v : values) {
ShopCacheDTO dto = parseShopCacheBase(v.toString());
String shopCacheJson = v.toString();
hvalsBytes += shopCacheJson.length();
ShopCacheDTO dto = parseShopCacheBase(shopCacheJson);
Shop s = dto.getShop();
if (s == null) {
continue;
@ -552,50 +563,18 @@ public class ShopController {
}
allShops.add(s);
}
timer.mark("parseShops");
timer.note("hvalsShops", values.size());
timer.note("hvalsBytes", hvalsBytes);
String sort = pageVo.getSort();
String order = pageVo.getOrder();
if (CharSequenceUtil.isNotBlank(sort)) {
allShops.sort((s1, s2) -> {
int compareResult = 0;
if ("saleCount".equals(sort)) {
Integer count1 = s1.getSaleCount();
Integer count2 = s2.getSaleCount();
Integer c1 = count1 == null ? 0 : count1;
Integer c2 = count2 == null ? 0 : count2;
compareResult = c1.compareTo(c2);
} else if ("shopScore".equals(sort)) {
BigDecimal score1 = s1.getShopScore() == null ? BigDecimal.ZERO : s1.getShopScore();
BigDecimal score2 = s2.getShopScore() == null ? BigDecimal.ZERO : s2.getShopScore();
compareResult = score1.compareTo(score2);
} else if ("shoprank".equals(sort)) {
Integer shoprank1 = s1.getShoprank() == null ? 0 : s1.getShoprank();
Integer shoprank2 = s2.getShoprank() == null ? 0 : s2.getShoprank();
compareResult = shoprank1.compareTo(shoprank2);
}
if ("desc".equalsIgnoreCase(order)) {
compareResult = -compareResult;
}
return compareResult;
});
}
// 稳定排序:用户端优先展示营业中的商家,后台仍将禁用商家置底。
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);
});
applyAdminShopListSort(allShops, pageVo);
} else {
applyUserShopListSort(allShops, pageVo);
String currentBusinessTime = LocalTime.now().format(BUSINESS_TIME_FORMATTER);
allShops.sort((s1, s2) -> compareUserShopPriority(s1, s2, currentBusinessTime));
}
timer.mark("sort");
int pageNumber = pageVo.getPageNumber() > 0 ? pageVo.getPageNumber() : 1;
int pageSize = pageVo.getPageSize() > 0 ? pageVo.getPageSize() : 10;
@ -615,21 +594,27 @@ public class ShopController {
productKeys.add("SHOP_PRODUCTS:" + s.getId());
}
List<String> productsJsonList = redisTemplateHelper.multiGet(productKeys);
timer.mark("mgetProducts");
long productBytes = 0L;
int productCount = 0;
if (productsJsonList != null && productsJsonList.size() == pageList.size()) {
for (int i = 0; i < pageList.size(); i++) {
String productsJson = productsJsonList.get(i);
if (CharSequenceUtil.isNotBlank(productsJson)) {
productBytes += productsJson.length();
List<ProductPageVO> productsReturn = new ArrayList<>();
List<ProductPageVO> products = JSONUtil.toList(productsJson, ProductPageVO.class);
productCount += products == null ? 0 : products.size();
if (hasKeyword) {
for (ProductPageVO p : products) {
if (p.getDelFlag() == 1 && p.getProductName() != null && p.getProductName().contains(shop.getKeyWord())) {
if (isSearchMatchedProduct(p, shop.getKeyWord())) {
p.setIsPush(1);
productsReturn.add(p);
}
}
}else{
for (ProductPageVO p : products) {
if (p.getDelFlag() == 1 && p.getIsPush() == 1) {
if (Integer.valueOf(1).equals(p.getDelFlag()) && Integer.valueOf(1).equals(p.getIsPush())) {
productsReturn.add(p);
}
}
@ -640,28 +625,40 @@ public class ShopController {
}
}
}
timer.mark("parseProducts");
timer.note("productBytes", productBytes);
timer.note("productCount", productCount);
}
fillGroupDeliveryTime(pageList, regionId);
timer.mark("deliveryTime");
fillBaseDeliveryFee(pageList, regionId);
timer.mark("baseFee");
Page<Shop> pageResult = new PageImpl<>(pageList, PageUtil.initPage(pageVo), allShops.size());
cacheDefaultGroupBuyPage(defaultPageCacheKey, pageList, allShops.size());
logSlowShopListQuery("redis", queryStartTime, allShops.size(), pageList.size(), regionId);
timer.mark("pageCacheWrite");
logShopListQuery("redis", timer, allShops.size(), pageList.size(), regionId);
return new ResultUtil<Page<Shop>>().setData(pageResult);
}
}
Page<Shop> page;
if (adminQuery) {
page = shopService.findByCondition(shop, PageUtil.initPage(pageVo));
timer.mark("dbQuery");
fillShopTakeawayAndProducts(page.getContent(), shop, false);
timer.mark("dbFill");
} else {
// 用户端:全量查询 → 挂 takeaway → 按多时段营业状态排序 → 再分页(与缓存路径一致)
Page<Shop> allPage = shopService.findByCondition(shop, Pageable.unpaged());
List<Shop> allShops = new ArrayList<>(allPage.getContent());
timer.mark("dbQuery");
timer.note("dbShops", allShops.size());
fillShopTakeawayOnly(allShops);
timer.mark("dbTakeaway");
applyUserShopListSort(allShops, pageVo);
String currentBusinessTime = LocalTime.now().format(BUSINESS_TIME_FORMATTER);
allShops.sort((s1, s2) -> compareUserShopPriority(s1, s2, currentBusinessTime));
timer.mark("sort");
int pageNumber = pageVo.getPageNumber() > 0 ? pageVo.getPageNumber() : 1;
int pageSize = pageVo.getPageSize() > 0 ? pageVo.getPageSize() : 10;
@ -671,15 +668,85 @@ public class ShopController {
? new ArrayList<>()
: new ArrayList<>(allShops.subList(fromIndex, toIndex));
fillShopProducts(pageList, shop);
timer.mark("dbProducts");
fillGroupDeliveryTime(pageList, shop.getRegionId());
timer.mark("deliveryTime");
fillBaseDeliveryFee(pageList, shop.getRegionId());
timer.mark("baseFee");
page = new PageImpl<>(pageList, PageUtil.initPage(pageVo), allShops.size());
}
cacheDefaultGroupBuyPage(defaultPageCacheKey, page.getContent(), page.getTotalElements());
logSlowShopListQuery("db", queryStartTime, page.getTotalElements(), page.getContent().size(), shop.getRegionId());
timer.mark("pageCacheWrite");
logShopListQuery("db", timer, page.getTotalElements(), page.getContent().size(), shop.getRegionId());
return new ResultUtil<Page<Shop>>().setData(page);
}
private void applyAdminShopListSort(List<Shop> allShops, PageVo pageVo) {
if (allShops == null || allShops.isEmpty()) {
return;
}
String shoprankOrder = getShoprankOrder(pageVo);
String sort = pageVo == null ? null : pageVo.getSort();
String order = pageVo == null ? null : pageVo.getOrder();
allShops.sort((s1, s2) -> {
int compareResult = Integer.compare(getAdminShopStatusOrder(s1), getAdminShopStatusOrder(s2));
if (compareResult != 0) {
return compareResult;
}
compareResult = compareShoprank(s1, s2, shoprankOrder);
if (compareResult != 0 || CharSequenceUtil.isBlank(sort)
|| "status".equals(sort) || "shoprank".equals(sort)) {
return compareResult;
}
compareResult = compareShopBySortField(s1, s2, sort);
if ("desc".equalsIgnoreCase(order)) {
compareResult = -compareResult;
}
return compareResult;
});
}
private int getAdminShopStatusOrder(Shop shop) {
Integer status = shop == null ? null : shop.getStatus();
if (ShopConstant.SHOP_STATUS_NORMAL.equals(status)) {
return 0;
}
return ShopConstant.SHOP_STATUS_LOCK.equals(status) ? 2 : 1;
}
private String getShoprankOrder(PageVo pageVo) {
if (pageVo == null) {
return "desc";
}
if ("shoprank".equals(pageVo.getSortOrder())) {
return CharSequenceUtil.isBlank(pageVo.getOrderOrder()) ? "desc" : pageVo.getOrderOrder();
}
if ("shoprank".equals(pageVo.getSort())) {
return CharSequenceUtil.isBlank(pageVo.getOrder()) ? "desc" : pageVo.getOrder();
}
return "desc";
}
private int compareShoprank(Shop s1, Shop s2, String order) {
Integer shoprank1 = s1.getShoprank() == null ? 0 : s1.getShoprank();
Integer shoprank2 = s2.getShoprank() == null ? 0 : s2.getShoprank();
int compareResult = shoprank1.compareTo(shoprank2);
return "asc".equalsIgnoreCase(order) ? compareResult : -compareResult;
}
private int compareShopBySortField(Shop s1, Shop s2, String sort) {
if ("saleCount".equals(sort)) {
Integer c1 = s1.getSaleCount() == null ? 0 : s1.getSaleCount();
Integer c2 = s2.getSaleCount() == null ? 0 : s2.getSaleCount();
return c1.compareTo(c2);
} else if ("shopScore".equals(sort)) {
BigDecimal score1 = s1.getShopScore() == null ? BigDecimal.ZERO : s1.getShopScore();
BigDecimal score2 = s2.getShopScore() == null ? BigDecimal.ZERO : s2.getShopScore();
return score1.compareTo(score2);
}
return 0;
}
private void applyUserShopListSort(List<Shop> allShops, PageVo pageVo) {
if (allShops == null || allShops.isEmpty() || pageVo == null) {
return;
@ -747,6 +814,9 @@ public class ShopController {
Map<String, List<ProductPageVO>> productsByShopId = new HashMap<>();
if (productList != null && productList.getRecords() != null) {
productList.getRecords().forEach(productPageVO -> {
if (CharSequenceUtil.isNotBlank(query.getKeyWord())) {
productPageVO.setIsPush(1);
}
productsByShopId.computeIfAbsent(productPageVO.getShopId(), key -> new ArrayList<>()).add(productPageVO);
});
}
@ -755,6 +825,14 @@ public class ShopController {
}
}
private boolean isSearchMatchedProduct(ProductPageVO product, String keyword) {
return product != null
&& Integer.valueOf(1).equals(product.getDelFlag())
&& CharSequenceUtil.isNotBlank(product.getProductName())
&& CharSequenceUtil.isNotBlank(keyword)
&& product.getProductName().contains(keyword);
}
private void fillShopTakeawayAndProducts(List<Shop> shops, Shop query) {
fillShopTakeawayAndProducts(shops, query, true);
}
@ -851,11 +929,42 @@ public class ShopController {
return ShopBusinessHourUtil.getBusinessTimeOrder(takeaway, currentTime);
}
private void logSlowShopListQuery(String source, long startTime, long totalElements, int pageSize, String regionId) {
long cost = System.currentTimeMillis() - startTime;
if (cost > 300) {
log.warn("app/shop/getByCondition slow source={}, cost={}ms, regionId={}, total={}, pageSize={}",
source, cost, regionId, totalElements, pageSize);
private void logShopListQuery(String source, ShopListStageTimer timer, long totalElements, int pageSize, String regionId) {
long cost = timer.totalMs();
if (cost > SHOP_LIST_SLOW_THRESHOLD_MS) {
log.warn("app/shop/getByCondition slow source={}, cost={}ms, regionId={}, total={}, pageSize={}, stages=[{}]",
source, cost, regionId, totalElements, pageSize, timer.detail());
} else if (log.isDebugEnabled()) {
log.debug("app/shop/getByCondition source={}, cost={}ms, regionId={}, total={}, pageSize={}, stages=[{}]",
source, cost, regionId, totalElements, pageSize, timer.detail());
}
}
/**
* 分段计时mark 记录距上一个 mark 的耗时note 记录传输字节数等辅助指标
* 用于定位 getByCondition 的耗时分布Redis 取数 / JSON 解析 / 排序 / DB
*/
private static final class ShopListStageTimer {
private final long startNano = System.nanoTime();
private final StringBuilder detail = new StringBuilder();
private long lastNano = startNano;
void mark(String stage) {
long now = System.nanoTime();
detail.append(stage).append('=').append((now - lastNano) / 1_000_000L).append("ms ");
lastNano = now;
}
void note(String name, Object value) {
detail.append(name).append('=').append(value).append(' ');
}
long totalMs() {
return (System.nanoTime() - startNano) / 1_000_000L;
}
String detail() {
return detail.toString().trim();
}
}
@ -1032,7 +1141,7 @@ public class ShopController {
if (shop.getStoreFlag() != null) {
oldShop.setStoreFlag(shop.getStoreFlag());
}
// 新增字段处理
if (shop.getShopImages() != null) {
oldShop.setShopImages(shop.getShopImages());

42
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/ShopServiceImpl.java

@ -187,13 +187,24 @@ public class ShopServiceImpl implements ShopService {
cq.where(list.toArray(arr));
if (adminQuery) {
List<Order> orderList = new ArrayList<>();
Expression<Integer> disabledOrder = cb.<Integer>selectCase()
.when(cb.equal(statusField, ShopConstant.SHOP_STATUS_LOCK), 1)
.otherwise(0);
orderList.add(cb.asc(disabledOrder));
orderList.add(cb.asc(statusField));
Expression<Integer> statusOrder = cb.<Integer>selectCase()
.when(cb.equal(statusField, ShopConstant.SHOP_STATUS_NORMAL), 0)
.when(cb.equal(statusField, ShopConstant.SHOP_STATUS_LOCK), 2)
.otherwise(1);
orderList.add(cb.asc(statusOrder));
Sort.Order shoprankOrder = null;
for (Sort.Order order : pageSort) {
if ("status".equals(order.getProperty())) {
if ("shoprank".equals(order.getProperty())) {
shoprankOrder = order;
break;
}
}
Path<Object> shoprankField = root.get("shoprank");
orderList.add(shoprankOrder != null && shoprankOrder.isAscending()
? cb.asc(shoprankField)
: cb.desc(shoprankField));
for (Sort.Order order : pageSort) {
if ("status".equals(order.getProperty()) || "shoprank".equals(order.getProperty())) {
continue;
}
Path<Object> sortField = root.get(order.getProperty());
@ -384,10 +395,25 @@ public class ShopServiceImpl implements ShopService {
// 第二层缓存:单独存储商品列表
String productsRedisKey = "SHOP_PRODUCTS:" + shopId;
String pushProductsRedisKey = "SHOP_PUSH_PRODUCTS:" + shopId;
if (productList != null && productList.getRecords() != null && !productList.getRecords().isEmpty()) {
redisTemplateHelper.set(productsRedisKey, JSONUtil.toJsonStr(productList.getRecords()));
List<ProductPageVO> products = productList.getRecords();
redisTemplateHelper.set(productsRedisKey, JSONUtil.toJsonStr(products));
List<ProductPageVO> pushProducts = new ArrayList<>();
for (ProductPageVO product : products) {
if (Integer.valueOf(1).equals(product.getDelFlag()) && Integer.valueOf(1).equals(product.getIsPush())) {
pushProducts.add(product);
}
}
if (!pushProducts.isEmpty()) {
redisTemplateHelper.set(pushProductsRedisKey, JSONUtil.toJsonStr(pushProducts));
} else {
redisTemplateHelper.delete(pushProductsRedisKey);
}
} else {
redisTemplateHelper.delete(productsRedisKey);
redisTemplateHelper.delete(pushProductsRedisKey);
}
}
@ -403,6 +429,8 @@ public class ShopServiceImpl implements ShopService {
// 同步删除第二层商品缓存
String productsRedisKey = "SHOP_PRODUCTS:" + shopId;
redisTemplateHelper.delete(productsRedisKey);
String pushProductsRedisKey = "SHOP_PUSH_PRODUCTS:" + shopId;
redisTemplateHelper.delete(pushProductsRedisKey);
}
private void removeGroupBuyDefaultPageCache(String regionId) {

20
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/DaQuReceiptRenderUtil.java

@ -12,6 +12,7 @@ import java.util.List;
public final class DaQuReceiptRenderUtil {
private static final String LINE = "--------------------------------";
private static final String TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
private static final String APPOINTMENT_TIME_PATTERN = "yyyy-MM-dd HH:mm";
private DaQuReceiptRenderUtil() {
}
@ -22,12 +23,14 @@ public final class DaQuReceiptRenderUtil {
List<MallRefundRecord> refunds = order.getMallRefundRecord();
boolean refundPrint = isRefundPrint(printReason);
boolean forcedOrderPrint = isOrderEventPrint(printReason);
boolean scanVerifyPrint = isScanVerifyPrint(printReason);
boolean hasRefund = refundPrint && refunds != null && !refunds.isEmpty();
centerLarge(sb, orderNo(order));
centerLarge(sb, orderTypeText(order, delivery, refundPrint, forcedOrderPrint));
centerLarge(sb, orderTypeText(order, delivery, refundPrint, forcedOrderPrint, scanVerifyPrint));
if (delivery != null && Integer.valueOf(1).equals(delivery.getAppointmentDelivery())) {
largeLeft(sb, "要求送达时间:" + formatTime(delivery.getMustFinishTime()));
left(sb, "要求送达时间:");
largeLeft(sb, formatAppointmentTime(delivery.getMustFinishTime()));
}
if (isFaceToFaceDelivery(order)) {
largeLeft(sb, "本单编号:" + defaultString(order.getNumberCode()));
@ -143,7 +146,7 @@ public final class DaQuReceiptRenderUtil {
return defaultString(order.getNumberCode());
}
private static String orderTypeText(MallOrderVO order, MallDeliveryOrder delivery, boolean refundPrint, boolean forcedOrderPrint) {
private static String orderTypeText(MallOrderVO order, MallDeliveryOrder delivery, boolean refundPrint, boolean forcedOrderPrint, boolean scanVerifyPrint) {
Integer status = order.getStatus();
if (delivery != null && Integer.valueOf(1).equals(delivery.getAppointmentDelivery())
&& !refundPrint) {
@ -167,6 +170,9 @@ public final class DaQuReceiptRenderUtil {
&& !Integer.valueOf(1).equals(order.getUserRequireMake())) {
return "待消费";
}
if (scanVerifyPrint) {
return "到店核销";
}
if (Integer.valueOf(5).equals(status)) {
return "已完成";
}
@ -196,6 +202,10 @@ public final class DaQuReceiptRenderUtil {
return StringUtils.containsIgnoreCase(printReason, "REFUND");
}
private static boolean isScanVerifyPrint(String printReason) {
return StringUtils.containsIgnoreCase(printReason, "SCAN_VERIFY");
}
private static boolean isFaceToFaceDelivery(MallOrderVO order) {
return Integer.valueOf(1).equals(order.getDeliveryType())
&& Integer.valueOf(3).equals(order.getOrderType());
@ -293,6 +303,10 @@ public final class DaQuReceiptRenderUtil {
return date == null ? "" : new SimpleDateFormat(TIME_PATTERN).format(date);
}
private static String formatAppointmentTime(Date date) {
return date == null ? "" : new SimpleDateFormat(APPOINTMENT_TIME_PATTERN).format(date);
}
private static String delNode(String text) {
return defaultString(text).replace("{", "").replace("}", "").replace("\"", "");
}

Loading…
Cancel
Save