7.21 增加返回在拼人数,前端显示修改,本地测试

This commit is contained in:
zhangsan 2025-07-21 11:24:41 +08:00
parent 39d3230bfd
commit 09769679af
15 changed files with 101 additions and 39 deletions

3
.gitignore vendored
View File

@ -33,4 +33,5 @@ build/
.vscode/
### Mac OS ###
.DS_Store
.DS_Store
/docs/local-zy.txt

View File

@ -38,7 +38,7 @@ services:
- SERVER_PORT=8091
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=123456
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/group_buying_sys?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/group-buying-sys?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false
- SPRING_DATASOURCE_DRIVER_CLASS_NAME=com.mysql.cj.jdbc.Driver
- SPRING_HIKARI_POOL_NAME=Retail_HikariCP
- REDIS_SDK_CONFIG_HOST=redis

View File

@ -13,6 +13,16 @@
Date: 19/07/2025 18:10:09
*/
-- 如果存在,则删除旧的数据库
DROP DATABASE IF EXISTS `group-buying-sys`;
-- 创建新的数据库(可根据需要指定字符集和排序规则)
CREATE DATABASE `group-buying-sys`
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- 切换到新创建的数据库
USE `group-buying-sys`;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

View File

@ -14,7 +14,7 @@ body{
/* ========== 轮播图 ========== */
.swiper-container{
width:100%;height:375px;position:relative;overflow:hidden;margin-top: 10px;
width:100%;height:375px;position:relative;overflow:hidden;
}
.swiper-wrapper{display:flex;transition:transform .3s;}
.swiper-slide{flex:0 0 100%;height:375px;}
@ -62,14 +62,7 @@ body{
}
/* ========== 拼单列表 ========== */
.group-buying {
background: #fff;
padding: 15px;
margin-bottom: 10px; /* 如果还想保留一点外边距 */
min-height: 230px; /* 根据需要调整数值 */
position: relative;
overflow: hidden;
}
.group-buying{background:#fff;padding:15px;margin-bottom:10px;position:relative;overflow:hidden;}
.section-title{
font-size:16px;font-weight:bold;margin-bottom:12px;position:relative;padding-left:10px;
}
@ -78,7 +71,7 @@ body{
width:3px;height:16px;background:#ff5000;border-radius:2px;
}
.group-users{height:180px;position:relative;overflow:hidden;}
.group-users{height:120px;position:relative;overflow:hidden;}
.user-list{position:absolute;top:0;left:0;width:100%;transition:transform .5s ease;}
.user-item{

View File

@ -73,9 +73,12 @@ document.addEventListener('DOMContentLoaded', () => {
/* ------------- 渲染统计信息 ------------- */
function renderStatistic(stat = {}) {
const { allTeamUserCount = 0 } = stat;
groupTitle.textContent = `${allTeamUserCount}人在抢,参与可立即拼成`;
soldBox.textContent = `${allTeamUserCount}人再抢`;
const {
allTeamUserCount = 0,
inTeamUserCount = 0
} = stat;
groupTitle.textContent = `${inTeamUserCount}人在抢,参与可立即拼成`;
soldBox.textContent = `${allTeamUserCount}人已抢`;
}
/* ------------- 渲染拼团列表 ------------- */
@ -86,7 +89,7 @@ document.addEventListener('DOMContentLoaded', () => {
}
userList.innerHTML = '';
list.forEach(t => userList.appendChild(makeItem(t, groupPrice)));
initUserMarquee();
initUserMarquee(3);
initCountdown();
}
@ -137,28 +140,61 @@ document.addEventListener('DOMContentLoaded', () => {
/* =====================================================
* 2. 拼单列表纵向轮播
* =================================================== */
function initUserMarquee() {
const items = userList.querySelectorAll('.user-item');
if (items.length <= 1) return;
function initUserMarquee(visibleCount = 3, interval = 3000, duration = 500) {
const box = document.querySelector('.group-users');
const listEl = userList;
let originals = Array.from(listEl.children);
const total = originals.length;
const itemH = items[0].offsetHeight;
userList.appendChild(items[0].cloneNode(true));
if (total === 0) return;
// 如果原本就 <= 可见数,直接定高,不滚
if (total <= visibleCount) {
const h0 = originals[0].offsetHeight;
box.style.height = (h0 * visibleCount) + 'px';
return;
}
let idx = 0;
userList.addEventListener('transitionend', () => {
if (idx >= items.length) {
userList.style.transition = 'none';
userList.style.transform = 'translateY(0)';
idx = 0;
void userList.offsetWidth;
// 1. 复制整份加入末尾
originals.forEach(item => listEl.appendChild(item.cloneNode(true)));
// 2. 重新测量单条高度(此时 DOM 完整)
const itemH = listEl.children[0].offsetHeight;
// 3. 设定窗口高度
box.style.height = (itemH * visibleCount) + 'px';
// 4. 状态
let index = 0;
let ticking = false;
function step() {
index++;
listEl.style.transition = `transform ${duration}ms ease`;
listEl.style.transform = `translateY(-${index * itemH}px)`;
}
listEl.addEventListener('transitionend', () => {
ticking = false;
// 5. 到达复制段的“第一帧”index === total就无缝重置
if (index === total) {
listEl.style.transition = 'none';
listEl.style.transform = 'translateY(0)';
index = 0;
// 强制 reflow 再恢复 transition
void listEl.offsetHeight;
listEl.style.transition = `transform ${duration}ms ease`;
}
});
setInterval(() => {
idx++;
userList.style.transition = 'transform .5s ease';
userList.style.transform = `translateY(${-idx * itemH}px)`;
}, 3000);
const timer = setInterval(() => {
if (!ticking) {
ticking = true;
step();
}
}, interval);
// 可选:鼠标悬停暂停
listEl.addEventListener('mouseenter', () => clearInterval(timer));
}
/* =====================================================

View File

@ -110,6 +110,8 @@ public class GoodsMarketResponseDTO {
private Integer allTeamCompleteCount;
// 参团人数总量 - 一个商品的总参团人数
private Integer allTeamUserCount;
//在拼人数 status=0 且当前时间在拼团有效时间内
private Integer inTeamUserCount;
}
}

View File

@ -18,7 +18,7 @@ spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://127.0.0.1:13306/group_buying_sys?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&useSSL=true
url: jdbc:mysql://127.0.0.1:13306/group-buying-sys?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&useSSL=true
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
pool-name: Retail_HikariCP

View File

@ -16,7 +16,7 @@ thread:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://mysql:3306/group_buying_sys?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false
url: jdbc:mysql://mysql:3306/group-buying-sys?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: 123456
hikari:

View File

@ -113,4 +113,17 @@
WHERE activity_id = #{activityId} and status IN (0, 1)
</select>
<select id="queryInUserCount" parameterType="java.util.Set" resultType="java.lang.Integer">
SELECT COALESCE(SUM(lock_count), 0)
FROM group_buy_order
WHERE team_id IN
<foreach item="teamId" collection="teamIds" open="(" separator="," close=")">
#{teamId}
</foreach>
AND status = 0
AND NOW() BETWEEN valid_start_time AND valid_end_time
</select>
</mapper>

View File

@ -35,8 +35,8 @@ public class TradeSettlementOrderServiceTest {
TradePaySuccessEntity tradePaySuccessEntity = new TradePaySuccessEntity();
tradePaySuccessEntity.setSource("s01");
tradePaySuccessEntity.setChannel("c01");
tradePaySuccessEntity.setUserId("smile02");
tradePaySuccessEntity.setOutTradeNo("334152190173");
tradePaySuccessEntity.setUserId("smile01");
tradePaySuccessEntity.setOutTradeNo("018750238789");
tradePaySuccessEntity.setOutTradeTime(new Date()); //交易时间
TradePaySettlementEntity tradePaySettlementEntity = tradeSettlementOrderService.settlementMarketPayOrder(tradePaySuccessEntity);
log.info("请求参数:{}", JSON.toJSONString(tradePaySuccessEntity));

View File

@ -27,7 +27,8 @@ public class MarketTradeControllerTest {
@Test
public void test_lockMarketPayOrder_mq() throws InterruptedException {
LockMarketPayOrderRequestDTO lockMarketPayOrderRequestDTO = new LockMarketPayOrderRequestDTO();
lockMarketPayOrderRequestDTO.setUserId("smile02");
lockMarketPayOrderRequestDTO.setUserId("smile01" +
"");
lockMarketPayOrderRequestDTO.setTeamId(null);
lockMarketPayOrderRequestDTO.setActivityId(100124L);
lockMarketPayOrderRequestDTO.setGoodsId("9890001");

View File

@ -20,5 +20,7 @@ public class TeamStatisticVO {
private Integer allTeamCompleteCount;
// 参团人数总量 - 一个商品的总参团人数
private Integer allTeamUserCount;
//在拼人数 status=0 且当前时间在拼团有效时间内
private Integer inTeamUserCount;
}

View File

@ -219,19 +219,21 @@ public class ActivityRepository implements IActivityRepository {
// 1. 根据活动ID查询所有拼团队伍id
List<String> teamIds = groupBuyOrderDao.queryActiveTeamIdsByActivityId(activityId);
if(null==teamIds || teamIds.isEmpty())
return new TeamStatisticVO(0, 0, 0);
return new TeamStatisticVO(0, 0, 0,0);
Set<String> teamIdSet = new HashSet<>(teamIds);
// 2. 统计数据
Integer allTeamCount = groupBuyOrderDao.queryAllTeamCount(teamIdSet); //该活动下的总拼团数
Integer allTeamCompleteCount = groupBuyOrderDao.queryAllTeamCompleteCount(teamIdSet); //该活动下已完成的拼团数
Integer allTeamUserCount = groupBuyOrderDao.queryAllUserCount(teamIdSet); //该活动下累计参与拼团人数
Integer inTeamUserCount = groupBuyOrderDao.queryInUserCount(teamIdSet); //该活动下在拼人数
// 3. 构建对象
return TeamStatisticVO.builder()
.allTeamCount(allTeamCount)
.allTeamCompleteCount(allTeamCompleteCount)
.allTeamUserCount(allTeamUserCount)
.inTeamUserCount(inTeamUserCount)
.build();
}

View File

@ -304,6 +304,7 @@ public class TradeRepository implements ITradeRepository {
task.setNotifyUrl(NotifyTypeEnumVO.HTTP.equals(notifyConfigVO.getNotifyType()) ? notifyConfigVO.getNotifyUrl() : null);
task.setNotifyCount(0);
task.setNotifyStatus(0);
//setParameterJson回调的消息返回拼团成功的团队id和外部交易单号list便于外部系统做后续处理如发货
task.setParameterJson(JSON.toJSONString(new HashMap<String, Object>() {{
put("teamId", team.getTeamId());
put("outTradeNoList", outTradeNoList);

View File

@ -51,4 +51,5 @@ public interface IGroupBuyOrderDao {
List<String> queryActiveTeamIdsByActivityId(Long activityId);
Integer queryInUserCount(@Param("teamIds") Set<String> teamIdSet);
}