diff --git a/.gitignore b/.gitignore
index d51d64e..50ca57a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,4 +33,5 @@ build/
.vscode/
### Mac OS ###
-.DS_Store
\ No newline at end of file
+.DS_Store
+/docs/local-zy.txt
diff --git a/docs/dev-ops/docker-compose-app.yml b/docs/dev-ops/docker-compose-app.yml
index 4b80fba..8c9e31f 100644
--- a/docs/dev-ops/docker-compose-app.yml
+++ b/docs/dev-ops/docker-compose-app.yml
@@ -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
diff --git a/docs/dev-ops/mysql/sql/0719group_buying_sys.sql b/docs/dev-ops/mysql/sql/0719group_buying_sys.sql
index 4781fbc..4a2fa8d 100644
--- a/docs/dev-ops/mysql/sql/0719group_buying_sys.sql
+++ b/docs/dev-ops/mysql/sql/0719group_buying_sys.sql
@@ -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;
diff --git a/docs/dev-ops/nginx/html/css/index.css b/docs/dev-ops/nginx/html/css/index.css
index f35e1f4..7ec93be 100644
--- a/docs/dev-ops/nginx/html/css/index.css
+++ b/docs/dev-ops/nginx/html/css/index.css
@@ -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{
diff --git a/docs/dev-ops/nginx/html/js/index.js b/docs/dev-ops/nginx/html/js/index.js
index 387a64e..3ac23e3 100644
--- a/docs/dev-ops/nginx/html/js/index.js
+++ b/docs/dev-ops/nginx/html/js/index.js
@@ -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));
}
/* =====================================================
diff --git a/group-buying-sys-api/src/main/java/edu/whut/api/dto/GoodsMarketResponseDTO.java b/group-buying-sys-api/src/main/java/edu/whut/api/dto/GoodsMarketResponseDTO.java
index 2b7094f..125e6cc 100644
--- a/group-buying-sys-api/src/main/java/edu/whut/api/dto/GoodsMarketResponseDTO.java
+++ b/group-buying-sys-api/src/main/java/edu/whut/api/dto/GoodsMarketResponseDTO.java
@@ -110,6 +110,8 @@ public class GoodsMarketResponseDTO {
private Integer allTeamCompleteCount;
// 参团人数总量 - 一个商品的总参团人数
private Integer allTeamUserCount;
+ //在拼人数 status=0 且当前时间在拼团有效时间内
+ private Integer inTeamUserCount;
}
}
diff --git a/group-buying-sys-app/src/main/resources/application-dev.yml b/group-buying-sys-app/src/main/resources/application-dev.yml
index f01bfb1..99ac3ef 100644
--- a/group-buying-sys-app/src/main/resources/application-dev.yml
+++ b/group-buying-sys-app/src/main/resources/application-dev.yml
@@ -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
diff --git a/group-buying-sys-app/src/main/resources/application-prod.yml b/group-buying-sys-app/src/main/resources/application-prod.yml
index a02dfd2..0e0c7c0 100644
--- a/group-buying-sys-app/src/main/resources/application-prod.yml
+++ b/group-buying-sys-app/src/main/resources/application-prod.yml
@@ -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:
diff --git a/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_order_mapper.xml b/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_order_mapper.xml
index 47eec1b..90a350d 100644
--- a/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_order_mapper.xml
+++ b/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_order_mapper.xml
@@ -113,4 +113,17 @@
WHERE activity_id = #{activityId} and status IN (0, 1)
+
+
+
+
diff --git a/group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/TradeSettlementOrderServiceTest.java b/group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/TradeSettlementOrderServiceTest.java
index fe4265a..558392b 100644
--- a/group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/TradeSettlementOrderServiceTest.java
+++ b/group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/TradeSettlementOrderServiceTest.java
@@ -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));
diff --git a/group-buying-sys-app/src/test/java/edu/whut/test/trigger/MarketTradeControllerTest.java b/group-buying-sys-app/src/test/java/edu/whut/test/trigger/MarketTradeControllerTest.java
index 22f4a92..de189ea 100644
--- a/group-buying-sys-app/src/test/java/edu/whut/test/trigger/MarketTradeControllerTest.java
+++ b/group-buying-sys-app/src/test/java/edu/whut/test/trigger/MarketTradeControllerTest.java
@@ -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");
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/model/valobj/TeamStatisticVO.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/model/valobj/TeamStatisticVO.java
index b471c72..829619a 100644
--- a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/model/valobj/TeamStatisticVO.java
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/model/valobj/TeamStatisticVO.java
@@ -20,5 +20,7 @@ public class TeamStatisticVO {
private Integer allTeamCompleteCount;
// 参团人数总量 - 一个商品的总参团人数
private Integer allTeamUserCount;
+ //在拼人数 status=0 且当前时间在拼团有效时间内
+ private Integer inTeamUserCount;
}
diff --git a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/ActivityRepository.java b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/ActivityRepository.java
index 7ebd94e..8e8da70 100644
--- a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/ActivityRepository.java
+++ b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/ActivityRepository.java
@@ -219,19 +219,21 @@ public class ActivityRepository implements IActivityRepository {
// 1. 根据活动ID查询所有拼团队伍id
List teamIds = groupBuyOrderDao.queryActiveTeamIdsByActivityId(activityId);
if(null==teamIds || teamIds.isEmpty())
- return new TeamStatisticVO(0, 0, 0);
+ return new TeamStatisticVO(0, 0, 0,0);
Set 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();
}
diff --git a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/TradeRepository.java b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/TradeRepository.java
index b609ba6..e6caaea 100644
--- a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/TradeRepository.java
+++ b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/TradeRepository.java
@@ -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() {{
put("teamId", team.getTeamId());
put("outTradeNoList", outTradeNoList);
diff --git a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/IGroupBuyOrderDao.java b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/IGroupBuyOrderDao.java
index b1cff0e..68f84f5 100644
--- a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/IGroupBuyOrderDao.java
+++ b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/IGroupBuyOrderDao.java
@@ -51,4 +51,5 @@ public interface IGroupBuyOrderDao {
List queryActiveTeamIdsByActivityId(Long activityId);
+ Integer queryInUserCount(@Param("teamIds") Set teamIdSet);
}