1. 商家提交注销申请 (logoutStore)
↓
2. 设置店铺状态为注销中 (storeStatus=-1, logoutFlag=1)
↓
3. 发送通知(7天冷静期)
↓
4. 7天内可撤回 (cancelLogoutStore)
↓
5. 超过7天后,定时任务自动删除店铺数据 (cancellationOfBusinessJob)
文件: StoreInfoServiceImpl.java:2691-2726
实现逻辑:
storeStatus = -1(注销中)logoutFlag = 1(注销标记)logoutTime(注销申请时间)logoutReason(注销原因)logoutCode(注销code)问题:
文件: StoreInfoServiceImpl.java:2743-2773
实现逻辑:
logoutFlag = 0storeStatus = 1(可用)问题:
logoutTime 是否超过7天文件: StoreMembershipCardJob.java:122-198
实现逻辑:
logoutFlag = 1 的店铺logoutTime 是否超过8天StoreUser.storeId问题:
life_user_order)order_coupon_middle)life_discount_coupon)life_coupon)life_discount_coupon_user)life_group_buy_main)store_comment、life_comment)life_notice)store_img)tag_store_relation)@Transactional,可能导致部分数据删除失败logoutFlag 是否为1(可能已被撤回)数据清理不完整
MerchantUserServiceImpl.resetToInitialStatus 应该清理更多数据时间逻辑不一致
缺少事务保护
缺少状态检查
logoutFlag 是否为1缺少异常处理
缺少详细日志
sevenDay 实际是8天后的时间,容易误导// 当前代码(错误)
calendar.add(Calendar.DAY_OF_YEAR, 8); // 8天后删除
// 应该改为
calendar.add(Calendar.DAY_OF_YEAR, 7); // 7天后删除
参考 MerchantUserServiceImpl.resetToInitialStatus,添加以下清理逻辑:
// 1. 查询订单ID列表
List<LifeUserOrder> orders = lifeUserOrderMapper.selectList(
new LambdaQueryWrapper<LifeUserOrder>().eq(LifeUserOrder::getStoreId, storeId)
);
List<String> orderIds = orders.stream().map(o -> o.getId().toString()).collect(Collectors.toList());
// 2. 删除订单-优惠券中间表
if (!orderIds.isEmpty()) {
orderCouponMiddleMapper.delete(
new LambdaQueryWrapper<OrderCouponMiddle>().in(OrderCouponMiddle::getOrderId, orderIds)
);
}
// 3. 删除订单
lifeUserOrderMapper.delete(
new LambdaQueryWrapper<LifeUserOrder>().eq(LifeUserOrder::getStoreId, storeId)
);
// 4. 删除优惠券
lifeDiscountCouponMapper.delete(
new LambdaQueryWrapper<LifeDiscountCoupon>().eq(LifeDiscountCoupon::getStoreId, storeId)
);
// 5. 删除代金券
lifeCouponMapper.delete(
new LambdaQueryWrapper<LifeCoupon>().eq(LifeCoupon::getStoreId, storeId)
);
// 6. 删除团购券
lifeGroupBuyMainMapper.delete(
new LambdaQueryWrapper<LifeGroupBuyMain>().eq(LifeGroupBuyMain::getStoreId, storeId)
);
// 7. 删除通知消息
lifeNoticeMapper.delete(
new LambdaQueryWrapper<LifeNotice>().eq(LifeNotice::getReceiverId, "store_" + storeUser.getPhone())
);
// 8. 删除店铺图片
storeImgMapper.delete(
new LambdaQueryWrapper<StoreImg>().eq(StoreImg::getStoreId, storeId)
);
// 9. 删除标签关系
tagStoreRelationMapper.delete(
new LambdaQueryWrapper<TagStoreRelation>().eq(TagStoreRelation::getStoreId, storeId)
);
// 10. 删除评论(根据实际表结构调整)
// storeCommentMapper.delete(...)
// lifeCommentMapper.delete(...)
@XxlJob("cancellationOfBusinessJob")
@Transactional(rollbackFor = Exception.class)
public void cancellationOfBusinessJob() {
// ... 删除逻辑
}
for (StoreInfo storeInfo : storeInfos) {
try {
// 再次检查状态
if (storeInfo.getLogoutFlag() != 1) {
log.warn("店铺 {} 的注销状态已变更,跳过删除", storeInfo.getId());
continue;
}
// 检查时间
if (storeInfo.getLogoutTime() == null) {
log.warn("店铺 {} 的注销时间为空,跳过删除", storeInfo.getId());
continue;
}
// 计算7天后的时间
Calendar calendar = Calendar.getInstance();
calendar.setTime(storeInfo.getLogoutTime());
calendar.add(Calendar.DAY_OF_YEAR, 7); // 改为7天
Date sevenDayLater = calendar.getTime();
if (new Date().compareTo(sevenDayLater) >= 0) {
// 执行删除逻辑
deleteStoreData(storeInfo);
log.info("成功删除店铺 {} 及其关联数据", storeInfo.getId());
}
} catch (Exception e) {
log.error("删除店铺 {} 失败: {}", storeInfo.getId(), e.getMessage(), e);
// 继续处理下一个店铺,不中断整个任务
}
}
public void cancelLogoutStore(StoreInfoVo storeInfo) {
StoreInfo storeIn = storeInfoMapper.selectOne(
new LambdaQueryWrapper<StoreInfo>().eq(StoreInfo::getId, storeInfo.getId())
);
if (storeIn == null) {
throw new IllegalArgumentException("店铺不存在");
}
// 检查是否还在冷静期内
if (storeIn.getLogoutTime() != null) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(storeIn.getLogoutTime());
calendar.add(Calendar.DAY_OF_YEAR, 7);
Date sevenDayLater = calendar.getTime();
if (new Date().compareTo(sevenDayLater) >= 0) {
throw new IllegalStateException("已超过7天冷静期,无法撤回注销申请");
}
}
// 检查当前状态
if (storeIn.getLogoutFlag() != 1) {
throw new IllegalStateException("店铺未处于注销状态,无法撤回");
}
// ... 后续恢复逻辑
}
P0(必须修复)
P1(重要)
P2(优化)
单元测试
集成测试
数据验证