8.6 修改'拼团展示列表逻辑'

This commit is contained in:
zhangsan 2025-08-06 21:09:19 +08:00
parent d32f8b9850
commit 7daa39d416
14 changed files with 202 additions and 175 deletions

View File

@ -1,20 +1,51 @@
/* ========== 全局 ========== */
*{
margin:0;padding:0;box-sizing:border-box;
margin:0;
padding:0;
box-sizing:border-box;
font-family:'PingFang SC','Helvetica Neue',Arial,sans-serif;
}
body{
background:#f5f5f5;
color:#333;
max-width:500px;
margin:0 auto;
position:relative;
padding-bottom:30px;
/* 最外层浏览器灰底(最深) */
html{
background:#e5e5e5;
}
/* ========== 轮播图 ========== */
/* ========== 版心包裹层(中灰) ========== */
/* body 中请包一层 <div class="app-wrapper">… */
.app-wrapper{
max-width:500px;
margin:0 auto;
background:#f3f4f6; /* ⭐ 中灰,与 html 有层次 */
padding:12px 0 60px; /* 顶 12px底 60px=底栏高 */
min-height:100vh;
border-radius:12px;
box-shadow:0 0 20px rgba(0,0,0,.10);
position:relative;
overflow-x:hidden;
}
/* body 仅语义,无视觉 */
body{ color:#333; }
/* —— 卡片公共阴影 —— */
.card{
background:#fff;
border-radius:12px;
box-shadow:0 2px 8px rgba(0,0,0,.05);
margin:0 16px 12px; /* 左右 16px 灰缝,底 12px 间隔 */
}
/* ========== 轮播图卡片 ========== */
.swiper-container{
width:100%;height:375px;position:relative;overflow:hidden;
composes: card; /* 写法若不支持 composes 就把下面三行展开 */
width:calc(100% - 32px);
height:375px;
margin:0 16px 12px;
border-radius:12px;
box-shadow:0 2px 8px rgba(0,0,0,.05);
position:relative;
overflow:hidden;
}
.swiper-wrapper{display:flex;transition:transform .3s;}
.swiper-slide{flex:0 0 100%;height:375px;}
@ -22,16 +53,24 @@ body{
.swiper-pagination{
position:absolute;bottom:10px;left:50%;
transform:translateX(-50%);display:flex;gap:6px;
transform:translateX(-50%);
display:flex;gap:6px;
}
.swiper-dot{
width:8px;height:8px;border-radius:50%;
background:rgba(255,255,255,.5);transition:all .3s;
background:rgba(255,255,255,.5);
transition:all .3s;
}
.swiper-dot.active{background:#ff5000;width:16px;border-radius:4px;}
/* ========== 商品信息 ========== */
.product-info{background:#fff;padding:15px;margin-bottom:10px;}
/* ========== 商品信息卡片 ========== */
.product-info{
background:#fff;
padding:16px;
margin:0 16px 12px;
border-radius:12px;
box-shadow:0 2px 8px rgba(0,0,0,.05);
}
.price-row{display:flex;align-items:center;margin-bottom:12px;}
.current-price{color:#ff5000;font-size:28px;font-weight:bold;}
@ -47,13 +86,11 @@ body{
.promo-row{display:flex;align-items:center;gap:6px;margin-top:6px;}
.promo-tag{
flex-shrink:0;
display:inline-block;
background:linear-gradient(90deg,#ff2c2c,#ff6b22);
color:#fff;font-size:12px;padding:2px 6px;border-radius:2px;
}
.promo-box{
display:inline-block;font-size:13px;padding:2px 6px;
border-radius:4px;font-weight:600;line-height:1.2;white-space:nowrap;
font-size:13px;padding:2px 6px;border-radius:4px;font-weight:600;white-space:nowrap;
}
.promo-box.drop,
.promo-box.sold{
@ -61,10 +98,19 @@ body{
color:#fff;
}
/* ========== 拼单列表 ========== */
.group-buying{background:#fff;padding:15px;margin-bottom:10px;position:relative;overflow:hidden;}
/* ========== 拼单区域卡片 ========== */
.group-buying{
background:#fff;
padding:16px;
margin:0 16px 12px;
border-radius:12px;
box-shadow:0 2px 8px rgba(0,0,0,.05);
position:relative;
overflow:hidden;
}
.section-title{
font-size:16px;font-weight:bold;margin-bottom:12px;position:relative;padding-left:10px;
font-size:16px;font-weight:bold;margin-bottom:12px;
position:relative;padding-left:10px;
}
.section-title::before{
content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);
@ -102,9 +148,15 @@ body{
/* ========== 底部操作栏 ========== */
.action-bar{
position:fixed;inset-inline:0;bottom:0;max-width:500px;margin:0 auto;
background:#fff;display:flex;height:60px;
box-shadow:0 -2px 10px rgba(0,0,0,.1);z-index:100;
position:fixed;
left:50%;bottom:0;transform:translateX(-50%);
width:100%;max-width:500px;
background:#fff;
display:flex;height:60px;
box-shadow:0 -2px 10px rgba(0,0,0,.08);
border-top:1px solid #e5e5e5;
border-radius:0 0 12px 12px;
z-index:100;
}
.action-btn{
flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
@ -121,13 +173,14 @@ body{
.btn-single{background:#ff9500;color:#fff;}
.btn-group {background:#ff5000;color:#fff;}
.btn-price{font-size:18px;font-weight:700;line-height:1;}
.btn-label{font-size:12px;line-height:1;}
.btn-price{font-size:18px;font-weight:700;}
.btn-label{font-size:12px;}
/* ========== 支付弹窗 ========== */
.payment-overlay{
position:fixed;inset:0;z-index:9999;
background:rgba(0,0,0,.55);display:flex;align-items:center;justify-content:center;
background:rgba(0,0,0,.55);
display:flex;align-items:center;justify-content:center;
backdrop-filter:blur(2px);
}
.payment-modal{

View File

@ -3,14 +3,24 @@
padding: 0;
box-sizing: border-box;
}
body {
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
padding-bottom: 20px;
min-height: 100vh;
/* 让整个浏览器窗口仍是淡灰渐变 */
html{
background: linear-gradient(135deg,#f5f7fa 0%,#c3cfe2 100%);
}
/* 把主体内容包在白底里 + 居中 + 投影 */
body{
max-width:500px;
margin:0 auto;
background:#fff; /* 白色版心 */
min-height:100vh; /* 满高sticky/fixed 才能正确定位 */
box-shadow:0 0 20px rgba(0,0,0,.08);
position:relative; /* 保留你原来的 relative 语义 */
padding-bottom:20px; /* 其余样式保持 */
font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
}
/* 头部样式 */
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
@ -46,12 +56,15 @@ body {
border: 1px solid rgba(255,255,255,0.3);
}
/* 仅修改 hover 这段 */
.back-btn:hover {
background: rgba(255,255,255,0.3);
transform: translateY(-50%) translateX(-2px);
/* transform: translateY(-50%) translateX(-2px); ❌ 这一行会导致上下抖动 */
transform: translateX(-2px); /* ✅ 只做水平小位移 */
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}
.header-content h1 {
font-size: 20px;
color: white;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 KiB

After

Width:  |  Height:  |  Size: 103 KiB

View File

@ -11,6 +11,7 @@
</head>
<body>
<div class="app-wrapper">
<!-- 顶部轮播图 -->
<div class="swiper-container">
<div class="swiper-wrapper">
@ -97,7 +98,7 @@
</div>
</div>
</template>
</div>
<!-- 逻辑脚本 -->
<script src="js/common.js" defer></script>
<script src="js/index.js"></script>

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小傅哥 - 拼团项目 - 订单明细</title>
<title>Smile - 拼团项目 - 订单明细</title>
<link rel="stylesheet" href="css/order-list.css">
<script src="js/common.js"></script>
</head>

View File

@ -10,6 +10,7 @@
<result column="activity_id" property="activityId"/>
<result column="start_time" property="startTime"/>
<result column="end_time" property="endTime"/>
<result column="valid_end_time" property="validEndTime" />
<result column="goods_id" property="goodsId"/>
<result column="source" property="source"/>
<result column="channel" property="channel"/>
@ -27,12 +28,12 @@
<insert id="insert" parameterType="edu.whut.infrastructure.dao.po.GroupBuyOrderList">
insert into group_buy_order_list(
user_id, team_id, order_id, activity_id, start_time,
end_time, goods_id, source, channel, original_price, pay_price,
end_time, valid_end_time, goods_id, source, channel, original_price, pay_price,
deduction_price, status, out_trade_no, biz_id, create_time, update_time
)
values(
#{userId}, #{teamId}, #{orderId}, #{activityId}, #{startTime},
#{endTime}, #{goodsId}, #{source}, #{channel}, #{originalPrice},#{payPrice},
#{endTime}, #{validEndTime}, #{goodsId}, #{source}, #{channel}, #{originalPrice},#{payPrice},
#{deductionPrice}, #{status}, #{outTradeNo}, #{bizId}, now(), now()
)
</insert>
@ -86,28 +87,20 @@
select out_trade_no from group_buy_order_list where team_id = #{teamId} and status = 1
</select>
<select id="queryInProgressUserGroupBuyOrderDetailListByUserId"
parameterType="edu.whut.infrastructure.dao.po.GroupBuyOrderList" resultMap="dataMap">
select user_id, team_id, out_trade_no
<select id="queryInProgressUserGroupBuyOrderDetailListByRandom"
parameterType="edu.whut.infrastructure.dao.po.GroupBuyOrderList"
resultMap="dataMap">
select user_id,team_id,out_trade_no
from group_buy_order_list
where activity_id = #{activityId} and user_id = #{userId} and status in (0, 1) and end_time > now()
order by id desc
where activity_id = #{activityId}
and user_id = #{userId}
and team_id in ( select team_id from group_buy_order where activity_id = #{activityId} and status = 0)
and status in (0, 1)
and valid_end_time > now()
order by rand() <!-- 这里改成随机排序 -->
limit #{count}
</select>
<select id="queryInProgressUserGroupBuyOrderDetailListByRandom"
parameterType="edu.whut.infrastructure.dao.po.GroupBuyOrderList" resultMap="dataMap">
select user_id, team_id, out_trade_no
from group_buy_order_list
where
activity_id = #{activityId} and
team_id in (select team_id from group_buy_order where activity_id = #{activityId} and status = 0) and
user_id != #{userId} and
status in (0, 1)
and end_time > now()
order by id desc
limit #{count}
</select>
<select id="queryInProgressUserGroupBuyOrderDetailListByActivityId" parameterType="java.lang.Long"
resultMap="dataMap">

View File

@ -23,9 +23,9 @@ public interface IActivityRepository {
boolean downgradeSwitch();
boolean cutRange(String userId);
List<UserGroupBuyOrderDetailEntity> queryInProgressUserGroupBuyOrderDetailListByOwner(Long activityId, String userId, Integer ownerCount);
List<UserGroupBuyOrderDetailEntity> queryInProgressUserGroupBuyOrderDetailListByRandom(Long activityId, String userId, Integer randomCount);
List<UserGroupBuyOrderDetailEntity> listRandomDetails(Long activityId, String userId, int randomCount);
TeamStatisticVO queryTeamStatisticByActivityId(Long activityId);
}

View File

@ -25,11 +25,13 @@ public interface IIndexGroupBuyMarketService {
*
* @param activityId 活动ID
* @param userId 用户ID
* @param ownerCount 个人数量
* @param randomCount 随机数量
* @return 用户拼团明细数据
*/
List<UserGroupBuyOrderDetailEntity> queryInProgressUserGroupBuyOrderDetailList(Long activityId, String userId, Integer ownerCount, Integer randomCount);
List<UserGroupBuyOrderDetailEntity> queryInProgressUserGroupBuyOrderDetailList(Long activityId,
String userId,
int randomCount);
/**
* 活动下的拼团队伍统计数据

View File

@ -10,7 +10,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
/**
@ -43,46 +42,14 @@ public class IndexGroupBuyMarketServiceImpl implements IIndexGroupBuyMarketServi
* 查询当前用户参与的ownerCount个拼团 + randomCount个随机其他拼团
*/
@Override
public List<UserGroupBuyOrderDetailEntity> queryInProgressUserGroupBuyOrderDetailList(
Long activityId, String userId, Integer ownerCount, Integer randomCount) {
List<UserGroupBuyOrderDetailEntity> unionAllList = new ArrayList<>();
Set<String> seenTeamIds = new LinkedHashSet<>(); // 记录已出现的 teamId保证自己优先的顺序
// 查询个人拼团数据自己
if (ownerCount != null && ownerCount != 0) {
List<UserGroupBuyOrderDetailEntity> ownerList =
repository.queryInProgressUserGroupBuyOrderDetailListByOwner(activityId, userId, ownerCount);
unionAllList.addAll(dedupByTeamId(ownerList, seenTeamIds)); // 先放自己并在 seen 里登记
public List<UserGroupBuyOrderDetailEntity> queryInProgressUserGroupBuyOrderDetailList(Long activityId,
String userId,
int randomCount) {
return randomCount <= 0
? Collections.emptyList()
: repository.listRandomDetails(activityId, userId, randomCount);
}
// 查询其他非个人拼团他人
if (randomCount != null && randomCount != 0) {
List<UserGroupBuyOrderDetailEntity> randomList =
repository.queryInProgressUserGroupBuyOrderDetailListByRandom(activityId, userId, randomCount);
unionAllList.addAll(dedupByTeamId(randomList, seenTeamIds)); // 过滤掉与自己重复的 team且列表内部去重
}
log.info("zy"+unionAllList.toString());
return unionAllList;
}
private static List<UserGroupBuyOrderDetailEntity> dedupByTeamId(
List<UserGroupBuyOrderDetailEntity> source,
Set<String> seenTeamIds) {
if (source == null || source.isEmpty()) return Collections.emptyList();
List<UserGroupBuyOrderDetailEntity> res = new ArrayList<>(source.size());
for (UserGroupBuyOrderDetailEntity e : source) {
if (e == null || e.getTeamId() == null) continue;
String key = e.getTeamId().toString();
if (seenTeamIds.add(key)) { // 第一次出现的 team 才保留
res.add(e);
}
}
return res;
}
/**
* 获取xx活动的拼团统计数据

View File

@ -134,44 +134,27 @@ public class ActivityRepository extends AbstractRepository implements IActivityR
return dccService.isCutRange(userId);
}
@Override
public List<UserGroupBuyOrderDetailEntity>
queryInProgressUserGroupBuyOrderDetailListByOwner(Long activityId, String userId, Integer ownerCount) {
// 1. 拿到原始列表
List<GroupBuyOrderList> raw = queryOrderLists(activityId, userId, ownerCount, false);
// 2. 直接组装并返回
return buildUserDetails(raw);
public List<UserGroupBuyOrderDetailEntity> listRandomDetails(Long activityId,
String userId,
int randomCount) {
if (randomCount <= 0) {
return Collections.emptyList();
}
@Override
public List<UserGroupBuyOrderDetailEntity>
queryInProgressUserGroupBuyOrderDetailListByRandom(Long activityId, String userId, Integer randomCount) {
// 1. 多查一点
List<GroupBuyOrderList> raw = queryOrderLists(activityId, userId, randomCount * 2, true);
if (raw.size() > randomCount) {
Collections.shuffle(raw);
raw = raw.subList(0, randomCount);
}
// 2. 组装
return buildUserDetails(raw);
}
/**
* 根据是否 random 选择不同 DAO返回原始的 GroupBuyOrderList 列表
*/
private List<GroupBuyOrderList> queryOrderLists(Long activityId, String userId, Integer count, boolean random) {
// 直接 DAO 调用省掉 queryOrderLists
GroupBuyOrderList req = new GroupBuyOrderList();
req.setActivityId(activityId);
req.setUserId(userId);
req.setCount(count);
req.setCount(randomCount);
log.info("Built GroupBuyOrderList req: {}", req);
List<GroupBuyOrderList> raw = Optional.ofNullable(
groupBuyOrderListDao.queryInProgressUserGroupBuyOrderDetailListByRandom(req))
.orElse(Collections.emptyList());
List<GroupBuyOrderList> list = random
? groupBuyOrderListDao.queryInProgressUserGroupBuyOrderDetailListByRandom(req)
: groupBuyOrderListDao.queryInProgressUserGroupBuyOrderDetailListByUserId(req);
return CollectionUtils.isEmpty(list)
? Collections.emptyList()
: list;
log.info("Raw result list ({} items): {}", raw.size(), raw);
return raw.isEmpty() ? Collections.emptyList() : buildUserDetails(raw);
}
/**

View File

@ -97,7 +97,8 @@ public class TradeRepository implements ITradeRepository {
}
/**
* 锁定营销预支付订单<br>
* 锁定营销预支付订单
* <p>
* - 新团自己创建团写入 group_buy_order再写入 group_buy_order_list<br>
* - 老团更新 lock_count满员时抛异常<br>
* 事务超时 500 ms成功后返回锁定好的订单信息
@ -106,27 +107,26 @@ public class TradeRepository implements ITradeRepository {
@Override
public MarketPayOrderEntity lockMarketPayOrder(GroupBuyOrderAggregate agg) {
// 从聚合中拆出各子实体聚合内已校验业务规则
// ------------- 聚合拆分已通过领域校验-------------
UserEntity user = agg.getUserEntity();
PayActivityEntity activity = agg.getPayActivityEntity();
PayDiscountEntity discount = agg.getPayDiscountEntity();
NotifyConfigVO notifyConfigVO = discount.getNotifyConfigVO();
Integer userTakeOrderCount = agg.getUserTakeOrderCount();
Integer userTakeTimes = agg.getUserTakeOrderCount();
/* ---------- 1. 处理 group_buy_order团单主表 ---------- */
String teamId = activity.getTeamId();
//自己发起拼团
Date groupValidEndTime; // 统一定义后面给明细单使用
// 1.1 自己发起拼团
if (StringUtils.isBlank(teamId)) {
// 新建团队随机 8 位数字作 teamId示例中用 RandomStringUtils线上可换雪花算法等
teamId = RandomStringUtils.randomNumeric(8);
// 日期处理
Date currentDate = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(currentDate);
calendar.add(Calendar.MINUTE, activity.getValidTime());
// 构建拼团订单
GroupBuyOrder orderPo = GroupBuyOrder.builder()
.teamId(teamId)
.activityId(activity.getActivityId())
@ -145,26 +145,28 @@ public class TradeRepository implements ITradeRepository {
.build();
groupBuyOrderDao.insert(orderPo);
} else {
// 参加已有团队先尝试把 lockCount +1 返回的是满足条件的记录个数
groupValidEndTime = orderPo.getValidEndTime(); // 直接取
}
// 1.2 参加已有团队
else {
int rows = groupBuyOrderDao.updateAddLockCount(teamId);
if (rows != 1) {
// 返回特定业务异常拼团已满员
throw new AppException(ResponseCode.E0005);
throw new AppException(ResponseCode.E0005); // 拼团已满员
}
// 更新成功后再查主单获取 validEndTime
GroupBuyOrder groupOrder = groupBuyOrderDao.queryGroupBuyTeamByTeamId(teamId);
groupValidEndTime = groupOrder.getValidEndTime();
}
/* ---------- 2. 写入 group_buy_order_list团单明细表 ---------- */
String orderId = RandomStringUtils.randomNumeric(12); // 订单号
// 计算时间确保开始和结束时间逻辑一致
Date orderStartTime = new Date(); // 当前时间作为订单开始时间
Calendar endTimeCalendar = Calendar.getInstance();
endTimeCalendar.setTime(orderStartTime); // 基于订单开始时间计算
endTimeCalendar.add(Calendar.MINUTE, 15);
Date orderEndTime = endTimeCalendar.getTime();
Date orderStartTime = new Date(); // 开始时间
Calendar endTimeCal = Calendar.getInstance();
endTimeCal.setTime(orderStartTime);
endTimeCal.add(Calendar.MINUTE, 15);
Date orderEndTime = endTimeCal.getTime();
//构建拼团明细单
GroupBuyOrderList orderListPo = GroupBuyOrderList.builder()
.userId(user.getUserId())
.teamId(teamId)
@ -172,6 +174,7 @@ public class TradeRepository implements ITradeRepository {
.activityId(activity.getActivityId())
.startTime(orderStartTime)
.endTime(orderEndTime)
.validEndTime(groupValidEndTime) // 新增字段
.goodsId(discount.getGoodsId())
.source(discount.getSource())
.channel(discount.getChannel())
@ -180,18 +183,20 @@ public class TradeRepository implements ITradeRepository {
.payPrice(discount.getPayPrice())
.status(TradeOrderStatusEnumVO.CREATE.getCode()) // 0 = 初始锁定
.outTradeNo(discount.getOutTradeNo())
// 构建 bizId 唯一值活动id_用户id_参与次数累加
.bizId(activity.getActivityId() + Constants.UNDERLINE + user.getUserId() + Constants.UNDERLINE + (userTakeOrderCount + 1))
.bizId(activity.getActivityId() // 活动id_用户id_参与次数
+ Constants.UNDERLINE
+ user.getUserId()
+ Constants.UNDERLINE
+ (userTakeTimes + 1))
.build();
try {
groupBuyOrderListDao.insert(orderListPo);
} catch (DuplicateKeyException e) {
// 幂等冲突同一 outTradeNo 已存在
throw new AppException(ResponseCode.INDEX_EXCEPTION);
throw new AppException(ResponseCode.INDEX_EXCEPTION); // 幂等冲突
}
/* ---------- 3. 返回领域对象给上层 ---------- */
/* ---------- 3. 返回领域对象 ---------- */
return MarketPayOrderEntity.builder()
.orderId(orderId)
.originalPrice(discount.getOriginalPrice())
@ -202,6 +207,7 @@ public class TradeRepository implements ITradeRepository {
.build();
}
/**
* 查询拼团进度当前已完成目标已锁定人数
*/

View File

@ -25,8 +25,6 @@ public interface IGroupBuyOrderListDao {
List<String> queryGroupBuyCompleteOrderOutTradeNoListByTeamId(String teamId);
List<GroupBuyOrderList> queryInProgressUserGroupBuyOrderDetailListByUserId(GroupBuyOrderList groupBuyOrderListReq);
List<GroupBuyOrderList> queryInProgressUserGroupBuyOrderDetailListByRandom(GroupBuyOrderList groupBuyOrderListReq);
/**

View File

@ -26,10 +26,12 @@ public class GroupBuyOrderList extends Page {
private String orderId;
/** 活动ID */
private Long activityId;
/** 活动开始时间 */
/** 锁单开始时间 */
private Date startTime;
/** 活动结束时间 */
/** 最晚锁单关闭时间 */
private Date endTime;
/** 当前拼团有效截止时间 */
private Date validEndTime;
/** 商品ID */
private String goodsId;
/** 渠道 */

View File

@ -19,6 +19,7 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@ -67,20 +68,28 @@ public class MarketIndexController implements IMarketIndexService {
// 4. 拼团队列 DTO 列表
//获取拼团展示列表
List<UserGroupBuyOrderDetailEntity> details = indexGroupBuyMarketService.queryInProgressUserGroupBuyOrderDetailList(
List<UserGroupBuyOrderDetailEntity> userGroupBuyOrderDetailEntities = indexGroupBuyMarketService.queryInProgressUserGroupBuyOrderDetailList(
trial.getGroupBuyActivityDiscountVO().getActivityId(),
req.getUserId(), 1, 4);
req.getUserId(), 4);
List<GoodsMarketResponseDTO.Team> teams = details.stream()
.map(d -> {
GoodsMarketResponseDTO.Team t = new GoodsMarketResponseDTO.Team();
BeanUtils.copyProperties(d, t);
t.setValidTimeCountdown(
GoodsMarketResponseDTO.Team.differenceDateTime2Str(
new Date(), d.getValidEndTime()));
return t;
})
.collect(Collectors.toList());
List<GoodsMarketResponseDTO.Team> teams = new ArrayList<>();
if (null != userGroupBuyOrderDetailEntities && !userGroupBuyOrderDetailEntities.isEmpty()) {
for (UserGroupBuyOrderDetailEntity userGroupBuyOrderDetailEntity : userGroupBuyOrderDetailEntities) {
GoodsMarketResponseDTO.Team team = GoodsMarketResponseDTO.Team.builder()
.userId(userGroupBuyOrderDetailEntity.getUserId())
.teamId(userGroupBuyOrderDetailEntity.getTeamId())
.activityId(userGroupBuyOrderDetailEntity.getActivityId())
.targetCount(userGroupBuyOrderDetailEntity.getTargetCount())
.completeCount(userGroupBuyOrderDetailEntity.getCompleteCount())
.lockCount(userGroupBuyOrderDetailEntity.getLockCount())
.validStartTime(userGroupBuyOrderDetailEntity.getValidStartTime())
.validEndTime(userGroupBuyOrderDetailEntity.getValidEndTime())
.validTimeCountdown(GoodsMarketResponseDTO.Team.differenceDateTime2Str(new Date(), userGroupBuyOrderDetailEntity.getValidEndTime()))
.outTradeNo(userGroupBuyOrderDetailEntity.getOutTradeNo())
.build();
teams.add(team);
}
}
// 5. 统计数据 DTO
TeamStatisticVO statVo = indexGroupBuyMarketService.queryTeamStatisticByActivityId(trial.getGroupBuyActivityDiscountVO().getActivityId());