Browse Source

对接拼团数据1

master
wangfukang 1 month ago
parent
commit
2983e4240d
  1. 16
      hiver-admin/test-output/test-report.html
  2. 12
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminMallOrderGroupController.java
  3. 11
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ShopAreaController.java
  4. 6
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ShopController.java
  5. 3
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/Shop.java
  6. 4
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/ShopArea.java
  7. 47
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/quartz/GroupBuyExpireTask.java
  8. 2
      hiver-modules/hiver-mall/src/main/resources/db/shop_area_express_errand_enabled.sql
  9. 2
      hiver-modules/hiver-mall/src/main/resources/db/shop_store_consume_only.sql
  10. 19
      hiver-modules/hiver-mall/src/main/resources/mapper/ShopAreaMapper.xml

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">九月 22, 2026 11:55:05</span></a>
<a href="#"><span class="badge badge-primary">九月 29, 2026 18:08:31</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>11:55:05 上午</span> / <span>0.025 secs</span></p>
<p class="text-sm"><span>18:08:32 下午</span> / <span>0.03 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.22.2026 11:55:05</span>
<span class='badge badge-danger'>09.22.2026 11:55:05</span>
<span class='badge badge-default'>0.025 secs</span>
<span class='badge badge-success'>09.29.2026 18:08:32</span>
<span class='badge badge-danger'>09.29.2026 18:08:32</span>
<span class='badge badge-default'>0.03 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>11:55:05</td>
<td>18:08:32</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>九月 22, 2026 11:55:05</h3>
<h3>九月 29, 2026 18:08:31</h3>
</div></div>
</div>
<div class="col-md-3">
<div class="card"><div class="card-body">
<p class="m-b-0">Ended</p>
<h3>九月 22, 2026 11:55:05</h3>
<h3>九月 29, 2026 18:08:32</h3>
</div></div>
</div>
<div class="col-md-3">

12
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminMallOrderGroupController.java

@ -97,6 +97,7 @@ public class AdminMallOrderGroupController {
private String productName;
private String productPicture;
private String productId;
private java.math.BigDecimal storeOriginalPrice;
private Shop shopItem;
}
@ -400,6 +401,7 @@ public class AdminMallOrderGroupController {
vo.setProductName(buildDisplayProductName(group, product));
vo.setProductPicture(group.getProductPicture());
vo.setProductId(group.getProductId());
vo.setStoreOriginalPrice(getStoreOriginalPrice(product == null ? null : product.getAttributeListPrice()));
vo.setShopItem(shop);
return vo;
}
@ -409,14 +411,10 @@ public class AdminMallOrderGroupController {
if (StringUtils.isBlank(productName) && product != null) {
productName = product.getProductName();
}
String specPrice = getFirstSpecPrice(product == null ? null : product.getAttributeListPrice());
if (StringUtils.isBlank(productName) || StringUtils.isBlank(specPrice)) {
return productName;
}
return productName + "-店内原价" + specPrice + "元";
return productName;
}
private String getFirstSpecPrice(String attributeListPrice) {
private java.math.BigDecimal getStoreOriginalPrice(String attributeListPrice) {
if (StringUtils.isBlank(attributeListPrice)) {
return null;
}
@ -426,7 +424,7 @@ public class AdminMallOrderGroupController {
return null;
}
JSONObject firstSpec = specs.getJSONObject(0);
return firstSpec == null ? null : firstSpec.getStr("specPrice");
return firstSpec == null ? null : firstSpec.getBigDecimal("specPrice");
} catch (Exception e) {
log.warn("解析商品规格原价失败 attributeListPrice={}: {}", attributeListPrice, e.getMessage());
return null;

11
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ShopAreaController.java

@ -311,6 +311,7 @@ public class ShopAreaController {
shopArea.setRadiusMeters(null);
shopArea.setGeoPolygon(null);
shopArea.setAreaKind(1);
shopArea.setExpressErrandEnabled(1);
return null;
}
Integer areaKind = shopArea.getAreaKind();
@ -319,6 +320,16 @@ public class ShopAreaController {
} else if (areaKind != 1 && areaKind != 2) {
return ResultUtil.error("区域类型仅支持:1校园区域,2社会区域");
}
if (shopArea.getAreaKind() != 2) {
shopArea.setExpressErrandEnabled(1);
} else {
Integer expressErrandEnabled = shopArea.getExpressErrandEnabled();
if (expressErrandEnabled == null) {
shopArea.setExpressErrandEnabled(1);
} else if (expressErrandEnabled != 0 && expressErrandEnabled != 1) {
return ResultUtil.error("快递/跑腿开关仅支持:1开启,0关闭");
}
}
Integer commissionRatio = shopArea.getCommissionRatio();
if (commissionRatio == null) {
shopArea.setCommissionRatio(0);

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

@ -145,6 +145,9 @@ public class ShopController {
shop.setRegion("");
shop.setRegionId(null);
}
if (shop.getStoreConsumeOnly() == null) {
shop.setStoreConsumeOnly(0);
}
shopService.save(shop);
@ -196,6 +199,9 @@ public class ShopController {
oldShop.setRegion("");
oldShop.setRegionId(null);
}
if (shop.getStoreConsumeOnly() != null) {
oldShop.setStoreConsumeOnly(shop.getStoreConsumeOnly());
}
UpdateUtils.copyNonNullProperties(shop, oldShop);
// 4. 更新数据库(此时更新的是带有完整数据的 oldShop,不会误清空其他字段)
shopService.update(oldShop);

3
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/Shop.java

@ -187,6 +187,9 @@ public class Shop extends HiverBaseEntity {
@ApiModelProperty(value = "是否支持堂食 0否 1是")
private Integer supportDineIn;
@ApiModelProperty(value = "是否只做到店消费 0否 1是")
private Integer storeConsumeOnly;
@ApiModelProperty(value = "是否支持商家自配送 0否 1是")
private Integer supportShopDelivery;

4
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/ShopArea.java

@ -83,6 +83,10 @@ public class ShopArea extends HiverBaseEntity {
@Column(nullable = false, columnDefinition = "int default 1")
private Integer areaKind = 1;
@ApiModelProperty(value = "社会区域是否开启快递/跑腿:1开启,0关闭")
@Column(nullable = false, columnDefinition = "int default 1")
private Integer expressErrandEnabled = 1;
@Transient
@TableField(exist = false)
@ApiModelProperty(value = "父节点名称")

47
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/quartz/GroupBuyExpireTask.java

@ -35,6 +35,8 @@ public class GroupBuyExpireTask {
private static final String SHOP_CACHE_PREFIX = "SHOP_CACHE:";
private static final String SHOP_PRODUCTS_PREFIX = "SHOP_PRODUCTS:";
private static final String SHOP_GROUP_ORDERS_PREFIX = "SHOP_GROUP_ORDERS:";
private static final String MOCK_SHOP_SALE_MAX_PREFIX = "MOCK_SHOP_SALE_MAX:";
private static final String MOCK_PRODUCT_SALE_MAX_PREFIX = "MOCK_PRODUCT_SALE_MAX:";
private static final int MOCK_GROUP_SHOP_COUNT = 20;
private static final int MOCK_GROUP_TARGET_MEMBERS = 2;
private static final int SALE_SHOP_COUNT = 40;
@ -202,18 +204,21 @@ public class GroupBuyExpireTask {
private boolean increaseShopSaleCache(Map.Entry<Object, Object> shopEntry, int increment) {
String shopId = getShopId(shopEntry);
ShopCacheDTO cacheDTO = parseShopCacheDTO(shopEntry.getValue());
Object latestShopCache = StringUtils.isBlank(shopId) ? null : redisTemplateHelper.hGet(buildShopCacheKey(MOCK_REGION_ID), shopId);
ShopCacheDTO cacheDTO = parseShopCacheDTO(latestShopCache != null ? latestShopCache : shopEntry.getValue());
if (StringUtils.isBlank(shopId) || cacheDTO == null || cacheDTO.getShop() == null || increment <= 0) {
return false;
}
Shop shop = cacheDTO.getShop();
int oldSaleCount = shop.getSaleCount() == null ? 0 : shop.getSaleCount();
if (!increaseProductTailWarnCache(shopId, increment)) {
return false;
}
shop.setSaleCount(oldSaleCount + increment);
int oldSaleCount = maxSaleValue(shop.getSaleCount(), redisTemplateHelper.hGet(buildMockShopSaleMaxKey(MOCK_REGION_ID), shopId));
int newSaleCount = oldSaleCount + increment;
shop.setSaleCount(newSaleCount);
redisTemplateHelper.hPut(buildShopCacheKey(MOCK_REGION_ID), shopId, JSONUtil.toJsonStr(cacheDTO));
redisTemplateHelper.hPut(buildMockShopSaleMaxKey(MOCK_REGION_ID), shopId, String.valueOf(newSaleCount));
return true;
}
@ -233,7 +238,9 @@ public class GroupBuyExpireTask {
List<Integer> productIndexes = new ArrayList<>();
for (int i = 0; i < productArray.size(); i++) {
JSONObject productObj = productArray.getJSONObject(i);
if (productObj != null && Integer.valueOf(1).equals(productObj.getInt("delFlag", 1))) {
if (productObj != null
&& StringUtils.isNotBlank(productObj.getStr("id"))
&& Integer.valueOf(1).equals(productObj.getInt("delFlag", 1))) {
productIndexes.add(i);
}
}
@ -244,10 +251,14 @@ public class GroupBuyExpireTask {
Collections.shuffle(productIndexes);
int productCount = Math.min(productIndexes.size(), totalIncrement);
List<Integer> productIncrements = randomPositiveParts(totalIncrement, productCount);
String productSaleMaxKey = buildMockProductSaleMaxKey(shopId);
for (int i = 0; i < productCount; i++) {
JSONObject productObj = productArray.getJSONObject(productIndexes.get(i));
int oldTailWarn = productObj.getInt("tailWarn", 0);
productObj.set("tailWarn", oldTailWarn + productIncrements.get(i));
String productId = productObj.getStr("id");
int oldTailWarn = maxSaleValue(productObj.getInt("tailWarn", 0), redisTemplateHelper.hGet(productSaleMaxKey, productId));
int newTailWarn = oldTailWarn + productIncrements.get(i);
productObj.set("tailWarn", newTailWarn);
redisTemplateHelper.hPut(productSaleMaxKey, productId, String.valueOf(newTailWarn));
}
redisTemplateHelper.set(productsKey, productArray.toString());
return true;
@ -381,4 +392,28 @@ public class GroupBuyExpireTask {
private String buildShopGroupOrdersKey(String shopId) {
return SHOP_GROUP_ORDERS_PREFIX + shopId;
}
private String buildMockShopSaleMaxKey(String regionId) {
return MOCK_SHOP_SALE_MAX_PREFIX + regionId;
}
private String buildMockProductSaleMaxKey(String shopId) {
return MOCK_PRODUCT_SALE_MAX_PREFIX + shopId;
}
private int maxSaleValue(Integer currentValue, Object cachedMaxValue) {
int current = currentValue == null ? 0 : Math.max(0, currentValue);
return Math.max(current, parseSaleValue(cachedMaxValue));
}
private int parseSaleValue(Object value) {
if (value == null) {
return 0;
}
try {
return Math.max(0, Integer.parseInt(value.toString()));
} catch (Exception e) {
return 0;
}
}
}

2
hiver-modules/hiver-mall/src/main/resources/db/shop_area_express_errand_enabled.sql

@ -0,0 +1,2 @@
ALTER TABLE `t_shop_area`
ADD COLUMN `express_errand_enabled` int(11) NOT NULL DEFAULT 1 COMMENT '社会区域是否开启快递/跑腿:1开启,0关闭';

2
hiver-modules/hiver-mall/src/main/resources/db/shop_store_consume_only.sql

@ -0,0 +1,2 @@
ALTER TABLE `t_shop`
ADD COLUMN `store_consume_only` TINYINT NOT NULL DEFAULT 0 COMMENT '是否只做到店消费 0否 1是' AFTER `support_dine_in`;

19
hiver-modules/hiver-mall/src/main/resources/mapper/ShopAreaMapper.xml

@ -23,11 +23,12 @@
<result column="radius_meters" property="radiusMeters" jdbcType="INTEGER" />
<result column="geo_polygon" property="geoPolygon" jdbcType="LONGVARCHAR" />
<result column="area_kind" property="areaKind" jdbcType="INTEGER" />
<result column="express_errand_enabled" property="expressErrandEnabled" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List" >
id, create_by, create_time, del_flag, update_by, update_time, is_parent, parent_id,
sort_order, status, title, is_canteen, delivery_enabled, parent_agent_id, parent_agent_name,
commission_ratio, center_lng, center_lat, radius_meters, geo_polygon, area_kind
commission_ratio, center_lng, center_lat, radius_meters, geo_polygon, area_kind, express_errand_enabled
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" >
select
@ -44,14 +45,14 @@
del_flag, update_by, update_time,
is_parent, parent_id, sort_order,
status, title, is_canteen, delivery_enabled, parent_agent_id, parent_agent_name,
commission_ratio, center_lng, center_lat, radius_meters, geo_polygon, area_kind)
commission_ratio, center_lng, center_lat, radius_meters, geo_polygon, area_kind, express_errand_enabled)
values (#{id,jdbcType=VARCHAR}, #{createBy,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP},
#{delFlag,jdbcType=INTEGER}, #{updateBy,jdbcType=VARCHAR}, #{updateTime,jdbcType=TIMESTAMP},
#{isParent,jdbcType=BIT}, #{parentId,jdbcType=VARCHAR}, #{sortOrder,jdbcType=DECIMAL},
#{status,jdbcType=INTEGER}, #{title,jdbcType=VARCHAR}, #{isCanteen,jdbcType=INTEGER}, #{deliveryEnabled,jdbcType=INTEGER},
#{parentAgentId,jdbcType=VARCHAR}, #{parentAgentName,jdbcType=VARCHAR}, #{commissionRatio,jdbcType=INTEGER},
#{centerLng,jdbcType=DECIMAL}, #{centerLat,jdbcType=DECIMAL}, #{radiusMeters,jdbcType=INTEGER},
#{geoPolygon,jdbcType=LONGVARCHAR}, #{areaKind,jdbcType=INTEGER})
#{geoPolygon,jdbcType=LONGVARCHAR}, #{areaKind,jdbcType=INTEGER}, #{expressErrandEnabled,jdbcType=INTEGER})
</insert>
<insert id="insertSelective" parameterType="cc.hiver.mall.entity.ShopArea" >
insert into t_shop_area
@ -119,6 +120,9 @@
<if test="areaKind != null" >
area_kind,
</if>
<if test="expressErrandEnabled != null" >
express_errand_enabled,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
@ -184,6 +188,9 @@
<if test="areaKind != null" >
#{areaKind,jdbcType=INTEGER},
</if>
<if test="expressErrandEnabled != null" >
#{expressErrandEnabled,jdbcType=INTEGER},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="cc.hiver.mall.entity.ShopArea" >
@ -249,6 +256,9 @@
<if test="areaKind != null" >
area_kind = #{areaKind,jdbcType=INTEGER},
</if>
<if test="expressErrandEnabled != null" >
express_errand_enabled = #{expressErrandEnabled,jdbcType=INTEGER},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
@ -273,7 +283,8 @@
center_lat = #{centerLat,jdbcType=DECIMAL},
radius_meters = #{radiusMeters,jdbcType=INTEGER},
geo_polygon = #{geoPolygon,jdbcType=LONGVARCHAR},
area_kind = #{areaKind,jdbcType=INTEGER}
area_kind = #{areaKind,jdbcType=INTEGER},
express_errand_enabled = #{expressErrandEnabled,jdbcType=INTEGER}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>
Loading…
Cancel
Save