7.21 增加返回在拼人数,前端显示修改,本地测试
This commit is contained in:
parent
39d3230bfd
commit
09769679af
1
.gitignore
vendored
1
.gitignore
vendored
@ -34,3 +34,4 @@ build/
|
|||||||
|
|
||||||
### Mac OS ###
|
### Mac OS ###
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
/docs/local-zy.txt
|
||||||
|
@ -38,7 +38,7 @@ services:
|
|||||||
- SERVER_PORT=8091
|
- SERVER_PORT=8091
|
||||||
- SPRING_DATASOURCE_USERNAME=root
|
- SPRING_DATASOURCE_USERNAME=root
|
||||||
- SPRING_DATASOURCE_PASSWORD=123456
|
- 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_DATASOURCE_DRIVER_CLASS_NAME=com.mysql.cj.jdbc.Driver
|
||||||
- SPRING_HIKARI_POOL_NAME=Retail_HikariCP
|
- SPRING_HIKARI_POOL_NAME=Retail_HikariCP
|
||||||
- REDIS_SDK_CONFIG_HOST=redis
|
- REDIS_SDK_CONFIG_HOST=redis
|
||||||
|
@ -13,6 +13,16 @@
|
|||||||
|
|
||||||
Date: 19/07/2025 18:10:09
|
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 NAMES utf8mb4;
|
||||||
SET FOREIGN_KEY_CHECKS = 0;
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
@ -14,7 +14,7 @@ body{
|
|||||||
|
|
||||||
/* ========== 轮播图 ========== */
|
/* ========== 轮播图 ========== */
|
||||||
.swiper-container{
|
.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-wrapper{display:flex;transition:transform .3s;}
|
||||||
.swiper-slide{flex:0 0 100%;height:375px;}
|
.swiper-slide{flex:0 0 100%;height:375px;}
|
||||||
@ -62,14 +62,7 @@ body{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ========== 拼单列表 ========== */
|
/* ========== 拼单列表 ========== */
|
||||||
.group-buying {
|
.group-buying{background:#fff;padding:15px;margin-bottom:10px;position:relative;overflow:hidden;}
|
||||||
background: #fff;
|
|
||||||
padding: 15px;
|
|
||||||
margin-bottom: 10px; /* 如果还想保留一点外边距 */
|
|
||||||
min-height: 230px; /* 根据需要调整数值 */
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.section-title{
|
.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;
|
||||||
}
|
}
|
||||||
@ -78,7 +71,7 @@ body{
|
|||||||
width:3px;height:16px;background:#ff5000;border-radius:2px;
|
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-list{position:absolute;top:0;left:0;width:100%;transition:transform .5s ease;}
|
||||||
|
|
||||||
.user-item{
|
.user-item{
|
||||||
|
@ -73,9 +73,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
/* ------------- 渲染统计信息 ------------- */
|
/* ------------- 渲染统计信息 ------------- */
|
||||||
function renderStatistic(stat = {}) {
|
function renderStatistic(stat = {}) {
|
||||||
const { allTeamUserCount = 0 } = stat;
|
const {
|
||||||
groupTitle.textContent = `${allTeamUserCount}人在抢,参与可立即拼成`;
|
allTeamUserCount = 0,
|
||||||
soldBox.textContent = `${allTeamUserCount}人再抢`;
|
inTeamUserCount = 0
|
||||||
|
} = stat;
|
||||||
|
groupTitle.textContent = `${inTeamUserCount}人在抢,参与可立即拼成`;
|
||||||
|
soldBox.textContent = `${allTeamUserCount}人已抢`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------- 渲染拼团列表 ------------- */
|
/* ------------- 渲染拼团列表 ------------- */
|
||||||
@ -86,7 +89,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
}
|
}
|
||||||
userList.innerHTML = '';
|
userList.innerHTML = '';
|
||||||
list.forEach(t => userList.appendChild(makeItem(t, groupPrice)));
|
list.forEach(t => userList.appendChild(makeItem(t, groupPrice)));
|
||||||
initUserMarquee();
|
initUserMarquee(3);
|
||||||
initCountdown();
|
initCountdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,28 +140,61 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
/* =====================================================
|
/* =====================================================
|
||||||
* 2. 拼单列表纵向轮播
|
* 2. 拼单列表纵向轮播
|
||||||
* =================================================== */
|
* =================================================== */
|
||||||
function initUserMarquee() {
|
function initUserMarquee(visibleCount = 3, interval = 3000, duration = 500) {
|
||||||
const items = userList.querySelectorAll('.user-item');
|
const box = document.querySelector('.group-users');
|
||||||
if (items.length <= 1) return;
|
const listEl = userList;
|
||||||
|
let originals = Array.from(listEl.children);
|
||||||
|
const total = originals.length;
|
||||||
|
|
||||||
const itemH = items[0].offsetHeight;
|
if (total === 0) return;
|
||||||
userList.appendChild(items[0].cloneNode(true));
|
// 如果原本就 <= 可见数,直接定高,不滚
|
||||||
|
if (total <= visibleCount) {
|
||||||
|
const h0 = originals[0].offsetHeight;
|
||||||
|
box.style.height = (h0 * visibleCount) + 'px';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let idx = 0;
|
// 1. 复制整份加入末尾
|
||||||
userList.addEventListener('transitionend', () => {
|
originals.forEach(item => listEl.appendChild(item.cloneNode(true)));
|
||||||
if (idx >= items.length) {
|
|
||||||
userList.style.transition = 'none';
|
// 2. 重新测量单条高度(此时 DOM 完整)
|
||||||
userList.style.transform = 'translateY(0)';
|
const itemH = listEl.children[0].offsetHeight;
|
||||||
idx = 0;
|
|
||||||
void userList.offsetWidth;
|
// 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(() => {
|
const timer = setInterval(() => {
|
||||||
idx++;
|
if (!ticking) {
|
||||||
userList.style.transition = 'transform .5s ease';
|
ticking = true;
|
||||||
userList.style.transform = `translateY(${-idx * itemH}px)`;
|
step();
|
||||||
}, 3000);
|
}
|
||||||
|
}, interval);
|
||||||
|
|
||||||
|
// 可选:鼠标悬停暂停
|
||||||
|
listEl.addEventListener('mouseenter', () => clearInterval(timer));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =====================================================
|
/* =====================================================
|
||||||
|
@ -110,6 +110,8 @@ public class GoodsMarketResponseDTO {
|
|||||||
private Integer allTeamCompleteCount;
|
private Integer allTeamCompleteCount;
|
||||||
// 参团人数总量 - 一个商品的总参团人数
|
// 参团人数总量 - 一个商品的总参团人数
|
||||||
private Integer allTeamUserCount;
|
private Integer allTeamUserCount;
|
||||||
|
//在拼人数 status=0 且当前时间在拼团有效时间内
|
||||||
|
private Integer inTeamUserCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ spring:
|
|||||||
datasource:
|
datasource:
|
||||||
username: root
|
username: root
|
||||||
password: 123456
|
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
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
hikari:
|
hikari:
|
||||||
pool-name: Retail_HikariCP
|
pool-name: Retail_HikariCP
|
||||||
|
@ -16,7 +16,7 @@ thread:
|
|||||||
spring:
|
spring:
|
||||||
datasource:
|
datasource:
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
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
|
username: root
|
||||||
password: 123456
|
password: 123456
|
||||||
hikari:
|
hikari:
|
||||||
|
@ -113,4 +113,17 @@
|
|||||||
WHERE activity_id = #{activityId} and status IN (0, 1)
|
WHERE activity_id = #{activityId} and status IN (0, 1)
|
||||||
</select>
|
</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>
|
</mapper>
|
||||||
|
@ -35,8 +35,8 @@ public class TradeSettlementOrderServiceTest {
|
|||||||
TradePaySuccessEntity tradePaySuccessEntity = new TradePaySuccessEntity();
|
TradePaySuccessEntity tradePaySuccessEntity = new TradePaySuccessEntity();
|
||||||
tradePaySuccessEntity.setSource("s01");
|
tradePaySuccessEntity.setSource("s01");
|
||||||
tradePaySuccessEntity.setChannel("c01");
|
tradePaySuccessEntity.setChannel("c01");
|
||||||
tradePaySuccessEntity.setUserId("smile02");
|
tradePaySuccessEntity.setUserId("smile01");
|
||||||
tradePaySuccessEntity.setOutTradeNo("334152190173");
|
tradePaySuccessEntity.setOutTradeNo("018750238789");
|
||||||
tradePaySuccessEntity.setOutTradeTime(new Date()); //交易时间
|
tradePaySuccessEntity.setOutTradeTime(new Date()); //交易时间
|
||||||
TradePaySettlementEntity tradePaySettlementEntity = tradeSettlementOrderService.settlementMarketPayOrder(tradePaySuccessEntity);
|
TradePaySettlementEntity tradePaySettlementEntity = tradeSettlementOrderService.settlementMarketPayOrder(tradePaySuccessEntity);
|
||||||
log.info("请求参数:{}", JSON.toJSONString(tradePaySuccessEntity));
|
log.info("请求参数:{}", JSON.toJSONString(tradePaySuccessEntity));
|
||||||
|
@ -27,7 +27,8 @@ public class MarketTradeControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void test_lockMarketPayOrder_mq() throws InterruptedException {
|
public void test_lockMarketPayOrder_mq() throws InterruptedException {
|
||||||
LockMarketPayOrderRequestDTO lockMarketPayOrderRequestDTO = new LockMarketPayOrderRequestDTO();
|
LockMarketPayOrderRequestDTO lockMarketPayOrderRequestDTO = new LockMarketPayOrderRequestDTO();
|
||||||
lockMarketPayOrderRequestDTO.setUserId("smile02");
|
lockMarketPayOrderRequestDTO.setUserId("smile01" +
|
||||||
|
"");
|
||||||
lockMarketPayOrderRequestDTO.setTeamId(null);
|
lockMarketPayOrderRequestDTO.setTeamId(null);
|
||||||
lockMarketPayOrderRequestDTO.setActivityId(100124L);
|
lockMarketPayOrderRequestDTO.setActivityId(100124L);
|
||||||
lockMarketPayOrderRequestDTO.setGoodsId("9890001");
|
lockMarketPayOrderRequestDTO.setGoodsId("9890001");
|
||||||
|
@ -20,5 +20,7 @@ public class TeamStatisticVO {
|
|||||||
private Integer allTeamCompleteCount;
|
private Integer allTeamCompleteCount;
|
||||||
// 参团人数总量 - 一个商品的总参团人数
|
// 参团人数总量 - 一个商品的总参团人数
|
||||||
private Integer allTeamUserCount;
|
private Integer allTeamUserCount;
|
||||||
|
//在拼人数 status=0 且当前时间在拼团有效时间内
|
||||||
|
private Integer inTeamUserCount;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -219,19 +219,21 @@ public class ActivityRepository implements IActivityRepository {
|
|||||||
// 1. 根据活动ID查询所有拼团队伍id
|
// 1. 根据活动ID查询所有拼团队伍id
|
||||||
List<String> teamIds = groupBuyOrderDao.queryActiveTeamIdsByActivityId(activityId);
|
List<String> teamIds = groupBuyOrderDao.queryActiveTeamIdsByActivityId(activityId);
|
||||||
if(null==teamIds || teamIds.isEmpty())
|
if(null==teamIds || teamIds.isEmpty())
|
||||||
return new TeamStatisticVO(0, 0, 0);
|
return new TeamStatisticVO(0, 0, 0,0);
|
||||||
Set<String> teamIdSet = new HashSet<>(teamIds);
|
Set<String> teamIdSet = new HashSet<>(teamIds);
|
||||||
|
|
||||||
// 2. 统计数据
|
// 2. 统计数据
|
||||||
Integer allTeamCount = groupBuyOrderDao.queryAllTeamCount(teamIdSet); //该活动下的总拼团数
|
Integer allTeamCount = groupBuyOrderDao.queryAllTeamCount(teamIdSet); //该活动下的总拼团数
|
||||||
Integer allTeamCompleteCount = groupBuyOrderDao.queryAllTeamCompleteCount(teamIdSet); //该活动下已完成的拼团数
|
Integer allTeamCompleteCount = groupBuyOrderDao.queryAllTeamCompleteCount(teamIdSet); //该活动下已完成的拼团数
|
||||||
Integer allTeamUserCount = groupBuyOrderDao.queryAllUserCount(teamIdSet); //该活动下累计参与拼团人数
|
Integer allTeamUserCount = groupBuyOrderDao.queryAllUserCount(teamIdSet); //该活动下累计参与拼团人数
|
||||||
|
Integer inTeamUserCount = groupBuyOrderDao.queryInUserCount(teamIdSet); //该活动下在拼人数
|
||||||
|
|
||||||
// 3. 构建对象
|
// 3. 构建对象
|
||||||
return TeamStatisticVO.builder()
|
return TeamStatisticVO.builder()
|
||||||
.allTeamCount(allTeamCount)
|
.allTeamCount(allTeamCount)
|
||||||
.allTeamCompleteCount(allTeamCompleteCount)
|
.allTeamCompleteCount(allTeamCompleteCount)
|
||||||
.allTeamUserCount(allTeamUserCount)
|
.allTeamUserCount(allTeamUserCount)
|
||||||
|
.inTeamUserCount(inTeamUserCount)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,6 +304,7 @@ public class TradeRepository implements ITradeRepository {
|
|||||||
task.setNotifyUrl(NotifyTypeEnumVO.HTTP.equals(notifyConfigVO.getNotifyType()) ? notifyConfigVO.getNotifyUrl() : null);
|
task.setNotifyUrl(NotifyTypeEnumVO.HTTP.equals(notifyConfigVO.getNotifyType()) ? notifyConfigVO.getNotifyUrl() : null);
|
||||||
task.setNotifyCount(0);
|
task.setNotifyCount(0);
|
||||||
task.setNotifyStatus(0);
|
task.setNotifyStatus(0);
|
||||||
|
//setParameterJson:回调的消息,返回拼团成功的团队id和外部交易单号list,便于外部系统做后续处理,如发货
|
||||||
task.setParameterJson(JSON.toJSONString(new HashMap<String, Object>() {{
|
task.setParameterJson(JSON.toJSONString(new HashMap<String, Object>() {{
|
||||||
put("teamId", team.getTeamId());
|
put("teamId", team.getTeamId());
|
||||||
put("outTradeNoList", outTradeNoList);
|
put("outTradeNoList", outTradeNoList);
|
||||||
|
@ -51,4 +51,5 @@ public interface IGroupBuyOrderDao {
|
|||||||
|
|
||||||
List<String> queryActiveTeamIdsByActivityId(Long activityId);
|
List<String> queryActiveTeamIdsByActivityId(Long activityId);
|
||||||
|
|
||||||
|
Integer queryInUserCount(@Param("teamIds") Set<String> teamIdSet);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user