Explorar el Código

商家端注销

lutong hace 5 horas
padre
commit
28b13c2022

+ 8 - 1
alien-entity/src/main/java/shop/alien/entity/store/StoreUser.java

@@ -24,6 +24,13 @@ import java.util.List;
 @ApiModel(value = "StoreUser对象", description = "门店用户")
 public class StoreUser extends Model<StoreUser> {
 
+    /** logout_flag:未注销 */
+    public static final int LOGOUT_FLAG_NORMAL = 0;
+    /** logout_flag:已注销(冷静期结束后) */
+    public static final int LOGOUT_FLAG_DONE = 1;
+    /** logout_flag:注销冷静期 */
+    public static final int LOGOUT_FLAG_COOLING = 2;
+
     public StoreUser() {
     }
 
@@ -97,7 +104,7 @@ public class StoreUser extends Model<StoreUser> {
     @TableField("updated_user_id")
     private Integer updatedUserId;
 
-    @ApiModelProperty(value = "注销标记, 0:未注销, 1:已注销")
+    @ApiModelProperty(value = "注销标记, 0:未注销, 1:已注销, 2:注销冷静期")
     @TableField("logout_flag")
     private Integer logoutFlag;
 

+ 6 - 0
alien-gateway/src/main/java/shop/alien/gateway/config/JwtTokenFilter.java

@@ -162,6 +162,12 @@ public class JwtTokenFilter implements GlobalFilter, Ordered {
                             //别问, 问就是约定俗成
                             map.put("code", 777);
                         }
+                        if (storeUser != null && storeUser.getLogoutFlag() != null
+                                && StoreUser.LOGOUT_FLAG_DONE == storeUser.getLogoutFlag()
+                                && !Integer.valueOf(-1).equals(storeUser.getStatus())) {
+                            map.put("msg", "你的账号已注销");
+                            map.put("code", 777);
+                        }
                         if (!token.equals(redisVal)) {
                             map.put("msg", "账号在别处登录");
                             //别问, 问就是约定俗成

+ 4 - 0
alien-gateway/src/main/java/shop/alien/gateway/controller/StoreUserController.java

@@ -69,6 +69,10 @@ public class StoreUserController {
         if (storeUser.getStatus() == 1) {
             return R.fail("账号被禁用");
         }
+        if (storeUser.getLogoutFlag() != null && StoreUser.LOGOUT_FLAG_DONE == storeUser.getLogoutFlag()
+                && !Integer.valueOf(-1).equals(storeUser.getStatus())) {
+            return R.fail("账号已注销");
+        }
         return Optional.ofNullable(storeUser).
                 map(user -> isPassword ? checkPassword(user, password) : storeUserService.createToKen(user)).
                 orElseGet(() -> R.fail("手机号不存在"));

+ 5 - 0
alien-gateway/src/main/java/shop/alien/gateway/service/impl/StoreUserServiceImpl.java

@@ -236,6 +236,11 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserGatewayMapper, St
             log.warn("账号被禁用 - userId: {}", userId);
             return R.fail("账号被禁用");
         }
+        if (storeUser.getLogoutFlag() != null && StoreUser.LOGOUT_FLAG_DONE == storeUser.getLogoutFlag()
+                && !Integer.valueOf(-1).equals(storeUser.getStatus())) {
+            log.warn("账号已注销 - userId: {}", userId);
+            return R.fail("账号已注销");
+        }
 
         // 3. 删除旧的token(参考switchingStates逻辑)
         baseRedisService.delete("store_" + storeUser.getPhone());

+ 19 - 13
alien-job/src/main/java/shop/alien/job/store/StoreMembershipCardJob.java

@@ -39,8 +39,9 @@ public class StoreMembershipCardJob {
     private final static String MEMBERSHIP_CARD_BYE_TYPE_HALF_YEAR = "2";
     //会员卡购买类型-年卡
     private final static String MEMBERSHIP_CARD_BYE_TYPE_YEAR = "3";
-    //会员卡购买类型-年卡
-    private final static Integer LOGOUT_FLAY = 1;
+    // 商家账号注销:0-未注销,1-已注销,2-注销冷静期
+    private final static Integer LOGOUT_FLAG_DONE = StoreUser.LOGOUT_FLAG_DONE;
+    private final static Integer LOGOUT_FLAG_COOLING = StoreUser.LOGOUT_FLAG_COOLING;
 
     private final StoreMembershipCardMapper storeMembershipCardMapper;
 
@@ -121,12 +122,14 @@ public class StoreMembershipCardJob {
      */
     @XxlJob("cancellationOfBusinessJob")
     public void cancellationOfBusinessJob() {
-        log.info("删除已申请注销超过7天的商家与用户: " + new Date());
+        log.info("处理已申请注销超过7天的商家与用户: " + new Date());
         int successCount = 0;
         int failCount = 0;
 
-        // 获取全部申请注销的商家用户
-        List<StoreUser> storeUsers = storeUserMapper.selectList(new LambdaQueryWrapper<StoreUser>().eq(StoreUser::getLogoutFlag, LOGOUT_FLAY));
+        // 获取处于注销冷静期的商家用户(含旧数据 logout_flag=1 且 status=-1)
+        List<StoreUser> storeUsers = storeUserMapper.selectList(new LambdaQueryWrapper<StoreUser>()
+                .and(w -> w.eq(StoreUser::getLogoutFlag, LOGOUT_FLAG_COOLING)
+                        .or(o -> o.eq(StoreUser::getLogoutFlag, LOGOUT_FLAG_DONE).eq(StoreUser::getStatus, -1))));
         for (StoreUser storeUser : storeUsers) {
             try {
                 if (null != storeUser.getLogoutTime()) {
@@ -140,25 +143,28 @@ public class StoreMembershipCardJob {
                     // 获取当前时间
                     Date date = new Date();
                     if (date.compareTo(sevenDay) >= 0) {
-                        // 删除已过注销时间的商家用户
-                        log.info("删除已注销超过7天的商家用户: userId={}, phone={}, logoutTime={}", 
+                        log.info("商家账号冷静期结束,标记为已注销: userId={}, phone={}, logoutTime={}",
                                 storeUser.getId(), storeUser.getPhone(), logoutTime);
-                        storeUserMapper.deleteById(storeUser.getId());
+                        storeUser.setLogoutFlag(LOGOUT_FLAG_DONE);
+                        if (Integer.valueOf(-1).equals(storeUser.getStatus())) {
+                            storeUser.setStatus(0);
+                        }
+                        storeUserMapper.updateById(storeUser);
                         alienStoreFeign.delMer(Boolean.TRUE, storeUser.getId().toString());
-                        //删除用户redis中的token
                         baseRedisService.delete("store_" + storeUser.getPhone());
+                        baseRedisService.delete("storePlatform_" + storeUser.getPhone());
                         successCount++;
                     }
                 }
             } catch (Exception e) {
                 failCount++;
-                log.error("删除商家用户失败: userId={}, phone={}, error={}", 
+                log.error("商家账号注销状态更新失败: userId={}, phone={}, error={}",
                         storeUser.getId(), storeUser.getPhone(), e.getMessage(), e);
             }
         }
-        
+
         // 获取全部申请注销的店铺
-        List<StoreInfo> storeInfos = storeInfoMapper.selectList(new LambdaQueryWrapper<StoreInfo>().eq(StoreInfo::getLogoutFlag, LOGOUT_FLAY));
+        List<StoreInfo> storeInfos = storeInfoMapper.selectList(new LambdaQueryWrapper<StoreInfo>().eq(StoreInfo::getLogoutFlag, LOGOUT_FLAG_DONE));
         for (StoreInfo storeInfo : storeInfos) {
             try {
                 if (null != storeInfo.getLogoutTime()) {
@@ -234,7 +240,7 @@ public class StoreMembershipCardJob {
         }
 
         // 获取全部申请注销的用户
-        List<LifeUser> lifeUsers = lifeUserMapper.selectList(new LambdaQueryWrapper<LifeUser>().eq(LifeUser::getLogoutFlag, LOGOUT_FLAY));
+        List<LifeUser> lifeUsers = lifeUserMapper.selectList(new LambdaQueryWrapper<LifeUser>().eq(LifeUser::getLogoutFlag, LOGOUT_FLAG_DONE));
         for (LifeUser lifeUser : lifeUsers) {
             try {
                 if (null != lifeUser.getLogoutTime()) {

+ 4 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/controller/StorePlatformLoginController.java

@@ -109,6 +109,10 @@ public class StorePlatformLoginController {
         if (storeUser.getStatus() == 1) {
             return R.fail("账号被禁用");
         }
+        if (storeUser.getLogoutFlag() != null && StoreUser.LOGOUT_FLAG_DONE == storeUser.getLogoutFlag()
+                && !Integer.valueOf(-1).equals(storeUser.getStatus())) {
+            return R.fail("账号已注销");
+        }
 
         return Optional.ofNullable(storeUser).
                 map(user -> isPassword ? checkPassword(user, password) : storePlatformLoginService.createToKen(user)).

+ 4 - 2
alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/MerchantUserServiceImpl.java

@@ -64,8 +64,10 @@ public class MerchantUserServiceImpl implements MerchantUserService {
             return storeUserVo;
         }
         
-        // 3. 如果用户状态为注销中(status=-1),计算注销倒计时
-        if (user.getStatus() == -1) {
+        // 3. 注销冷静期(logout_flag=2,兼容旧数据 status=-1)计算倒计时
+        boolean logoutCooling = StoreUser.LOGOUT_FLAG_COOLING == user.getLogoutFlag()
+                || (StoreUser.LOGOUT_FLAG_DONE == user.getLogoutFlag() && Integer.valueOf(-1).equals(user.getStatus()));
+        if (logoutCooling) {
             try {
                 // 将注销时间转换为LocalDateTime
                 LocalDateTime logoutDateTime = user.getLogoutTime()

+ 1 - 1
alien-store/src/main/java/shop/alien/store/service/LifeUserOrderService.java

@@ -177,7 +177,7 @@ public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeU
             }
             ;
             map.put("abnormalStateFlag", 0);
-            if (deleteFlag == 1 || storeStatus == 1 || logoutFlag == 1) {
+            if (deleteFlag == 1 || storeStatus == 1 || logoutFlag == 1 || logoutFlag == 2) {
                 map.put("abnormalStateFlag", 1);
             }
             // 营业状态

+ 116 - 48
alien-store/src/main/java/shop/alien/store/service/impl/StoreUserServiceImpl.java

@@ -112,7 +112,7 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
         StoreUser user = this.getOne(lambdaQueryWrapper);
         StoreUserVo storeUserVo = new StoreUserVo();
         if (user != null) {
-            if (user.getStatus() == -1) {
+            if (isStoreUserLogoutCooling(user) && user.getLogoutTime() != null) {
                 LocalDateTime localDateTime = user.getLogoutTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                 LocalDateTime future = localDateTime.plusDays(7);
                 LocalDateTime now = LocalDateTime.now();
@@ -477,16 +477,12 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
                 final int filterStatus = status;
                 subAccountMap = subAccountList == null ? new HashMap<>() : subAccountList.stream()
                         .filter(u -> u.getDeleteFlag() != null && u.getDeleteFlag() == 0)
-                        .filter(u -> {
-                            if (filterStatus == -1) return u.getStatus() != null && u.getStatus() == -1;
-                            return (u.getStatus() != null && u.getStatus() == 2) || (u.getLogoutFlag() != null && u.getLogoutFlag() == 1);
-                        })
+                        .filter(u -> filterStatus == -1 ? isStoreUserLogoutCooling(u) : isStoreUserLoggedOut(u))
                         .collect(Collectors.toMap(StoreUser::getId, u -> u, (a, b) -> a));
             } else {
                 subAccountMap = subAccountList == null ? new HashMap<>() : subAccountList.stream()
                         .filter(u -> u.getDeleteFlag() != null && u.getDeleteFlag() == 0
-                                && (u.getLogoutFlag() == null || u.getLogoutFlag() == 0)
-                                && (u.getStatus() == null || (u.getStatus() != -1 && u.getStatus() != 2)))
+                                && !isStoreUserLogoutCooling(u) && !isStoreUserLoggedOut(u))
                         .collect(Collectors.toMap(StoreUser::getId, u -> u, (a, b) -> a));
             }
             List<StorePlatformUserRole> filteredRoles = new ArrayList<>();
@@ -500,9 +496,7 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
                 // 状态筛选:选「注销中/已注销」时以 store_user 为准(已由 subAccountMap 限定);否则以 role.status 为准
                 int rowStatus;
                 if (status != null && (status == -1 || status == 2)) {
-                    rowStatus = (subAccount.getStatus() != null && subAccount.getStatus() == -1) ? -1
-                            : ((subAccount.getStatus() != null && subAccount.getStatus() == 2) || (subAccount.getLogoutFlag() != null && subAccount.getLogoutFlag() == 1)) ? 2
-                            : (subAccount.getStatus() != null ? subAccount.getStatus() : 0);
+                    rowStatus = resolveLogoutRowStatus(subAccount);
                 } else {
                     rowStatus = role.getStatus() != null ? role.getStatus() : (subAccount.getStatus() != null ? subAccount.getStatus() : 0);
                 }
@@ -546,10 +540,15 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
                 storeUserVo.setId(mainId != null ? mainId : subAccount.getId());
                 storeUserVo.setSubAccountId(subAccount.getId());
                 storeUserVo.setParentAccountId(mainId);
-                int rowStatus = role.getStatus() != null ? role.getStatus() : (subAccount.getStatus() != null ? subAccount.getStatus() : 0);
+                int rowStatus;
+                if (status != null && (status == -1 || status == 2)) {
+                    rowStatus = resolveLogoutRowStatus(subAccount);
+                } else {
+                    rowStatus = role.getStatus() != null ? role.getStatus() : (subAccount.getStatus() != null ? subAccount.getStatus() : 0);
+                }
                 storeUserVo.setStatus(rowStatus);
                 storeUserVo.setSwitchStatus(rowStatus == 0);
-                storeUserVo.setStatusName(rowStatus == -1 ? "注销中" : rowStatus == 2 ? "已注销" : (rowStatus == 1 ? "禁用" : "启用"));
+                storeUserVo.setStatusName(rowStatus == -1 ? "注销冷静期" : rowStatus == 2 ? "已注销" : (rowStatus == 1 ? "禁用" : "启用"));
                 storeUserVo.setPhone(subAccount.getPhone());
                 if (mainAccount != null) {
                     storeUserVo.setParentAccountPhone(mainAccount.getPhone());
@@ -563,14 +562,25 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
             return R.data(storeUserVoIPage);
         }
 
-        // 主账号分支:直接查库返回最新 status,主账号页面展示子账号数量(按 store_platform_user_role 统计);排除注销、已注销
+        // 主账号分支:直接查库返回最新 status,主账号页面展示子账号数量(按 store_platform_user_role 统计);排除注销冷静期、已注销
         LambdaQueryWrapper<StoreUser> storeUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
         storeUserLambdaQueryWrapper.eq(StoreUser::getDeleteFlag, 0)
                 .like(StringUtils.isNotEmpty(id), StoreUser::getId, id)
                 .like(StringUtils.isNotEmpty(phone), StoreUser::getPhone, phone)
-                .eq(status != null, StoreUser::getStatus, status)
                 .eq(StoreUser::getAccountType, 1)
                 .orderByDesc(StoreUser::getCreatedTime);
+        if (status != null && status == -1) {
+            storeUserLambdaQueryWrapper.and(w -> w.eq(StoreUser::getLogoutFlag, StoreUser.LOGOUT_FLAG_COOLING)
+                    .or(o -> o.eq(StoreUser::getLogoutFlag, StoreUser.LOGOUT_FLAG_DONE).eq(StoreUser::getStatus, -1)));
+        } else if (status != null && status == 2) {
+            storeUserLambdaQueryWrapper.eq(StoreUser::getLogoutFlag, StoreUser.LOGOUT_FLAG_DONE)
+                    .and(w -> w.isNull(StoreUser::getStatus).or().ne(StoreUser::getStatus, -1));
+        } else if (status != null) {
+            storeUserLambdaQueryWrapper.eq(StoreUser::getStatus, status)
+                    .and(w -> w.isNull(StoreUser::getLogoutFlag).or().eq(StoreUser::getLogoutFlag, StoreUser.LOGOUT_FLAG_NORMAL));
+        } else {
+            storeUserLambdaQueryWrapper.and(w -> w.isNull(StoreUser::getLogoutFlag).or().eq(StoreUser::getLogoutFlag, StoreUser.LOGOUT_FLAG_NORMAL));
+        }
 
         IPage<StoreUser> storeUsers = storeUserMapper.selectPage(page, storeUserLambdaQueryWrapper);
         BeanUtils.copyProperties(storeUsers, storeUserVoIPage);
@@ -581,11 +591,14 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
             BeanUtils.copyProperties(storeUser, vo);
             vo.setPassword(null);
             vo.setPayPassword(null);
-            // 主账号分页:返回最新 status(0 启用 / 1 禁用),前端展示启用/禁用
-            Integer latestStatus = storeUser.getStatus() != null ? storeUser.getStatus() : 0;
-            vo.setStatus(latestStatus);
-            vo.setSwitchStatus(latestStatus == 0);
-            vo.setStatusName(latestStatus == 1 ? "禁用" : "启用");
+            // 主账号分页:返回最新 status;注销场景展示冷静期/已注销
+            int rowStatus = resolveLogoutRowStatus(storeUser);
+            if (rowStatus == 0 || rowStatus == 1) {
+                rowStatus = storeUser.getStatus() != null ? storeUser.getStatus() : 0;
+            }
+            vo.setStatus(rowStatus);
+            vo.setSwitchStatus(rowStatus == 0);
+            vo.setStatusName(rowStatus == -1 ? "注销冷静期" : rowStatus == 2 ? "已注销" : (rowStatus == 1 ? "禁用" : "启用"));
             int childCount = countSubAccountUserIdsByStoreId(storeUser.getStoreId(), storeUser.getId());
             vo.setChildAccountCount(childCount);
             List<Integer> childUserIds = getSubAccountUserIdsByStoreId(storeUser.getStoreId(), storeUser.getId());
@@ -763,17 +776,33 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
     @Override
     public String exportExcel(String id, String phone, String status, Integer accountType) throws IOException {
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-        // 主账号导出:与 getStoreUserList 主账号分支一致,子账号数量按 store_platform_user_role 统计;排除注销中、已注销
+        // 主账号导出:与 getStoreUserList 主账号分支一致
         if (accountType == 1) {
             LambdaQueryWrapper<StoreUser> wrapper = new LambdaQueryWrapper<>();
             wrapper.eq(StoreUser::getDeleteFlag, 0)
                     .like(StringUtils.isNotEmpty(id), StoreUser::getId, id)
                     .like(StringUtils.isNotEmpty(phone), StoreUser::getPhone, phone)
-                    .eq(StringUtils.isNotEmpty(status), StoreUser::getStatus, status)
                     .eq(StoreUser::getAccountType, 1)
-                    .and(w -> w.isNull(StoreUser::getLogoutFlag).or().eq(StoreUser::getLogoutFlag, 0))
-                    .and(w -> w.isNull(StoreUser::getStatus).or().in(StoreUser::getStatus, 0, 1))
                     .orderByDesc(StoreUser::getCreatedTime);
+            Integer statusInt = null;
+            if (StringUtils.isNotEmpty(status)) {
+                try {
+                    statusInt = Integer.parseInt(status.trim());
+                } catch (NumberFormatException ignored) {
+                }
+            }
+            if (statusInt != null && statusInt == -1) {
+                wrapper.and(w -> w.eq(StoreUser::getLogoutFlag, StoreUser.LOGOUT_FLAG_COOLING)
+                        .or(o -> o.eq(StoreUser::getLogoutFlag, StoreUser.LOGOUT_FLAG_DONE).eq(StoreUser::getStatus, -1)));
+            } else if (statusInt != null && statusInt == 2) {
+                wrapper.eq(StoreUser::getLogoutFlag, StoreUser.LOGOUT_FLAG_DONE)
+                        .and(w -> w.isNull(StoreUser::getStatus).or().ne(StoreUser::getStatus, -1));
+            } else if (statusInt != null) {
+                wrapper.eq(StoreUser::getStatus, statusInt)
+                        .and(w -> w.isNull(StoreUser::getLogoutFlag).or().eq(StoreUser::getLogoutFlag, StoreUser.LOGOUT_FLAG_NORMAL));
+            } else {
+                wrapper.and(w -> w.isNull(StoreUser::getLogoutFlag).or().eq(StoreUser::getLogoutFlag, StoreUser.LOGOUT_FLAG_NORMAL));
+            }
             List<StoreUser> storeUsers = storeUserMapper.selectList(wrapper);
             List<StoreUserExcelVo> storeUserExcelVoList = new ArrayList<>();
             int serialNumber = 0;
@@ -825,16 +854,12 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
             final int filterStatus = statusInt;
             subAccountMap = subAccountList == null ? new HashMap<>() : subAccountList.stream()
                     .filter(u -> u.getDeleteFlag() != null && u.getDeleteFlag() == 0)
-                    .filter(u -> {
-                        if (filterStatus == -1) return u.getStatus() != null && u.getStatus() == -1;
-                        return (u.getStatus() != null && u.getStatus() == 2) || (u.getLogoutFlag() != null && u.getLogoutFlag() == 1);
-                    })
+                    .filter(u -> filterStatus == -1 ? isStoreUserLogoutCooling(u) : isStoreUserLoggedOut(u))
                     .collect(Collectors.toMap(StoreUser::getId, u -> u, (a, b) -> a));
         } else {
             subAccountMap = subAccountList == null ? new HashMap<>() : subAccountList.stream()
                     .filter(u -> u.getDeleteFlag() != null && u.getDeleteFlag() == 0
-                            && (u.getLogoutFlag() == null || u.getLogoutFlag() == 0)
-                            && (u.getStatus() == null || (u.getStatus() != -1 && u.getStatus() != 2)))
+                            && !isStoreUserLogoutCooling(u) && !isStoreUserLoggedOut(u))
                     .collect(Collectors.toMap(StoreUser::getId, u -> u, (a, b) -> a));
         }
         List<StorePlatformUserRole> filteredRoles = new ArrayList<>();
@@ -847,9 +872,7 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
                 continue;
             int rowStatus;
             if (statusInt != null && (statusInt == -1 || statusInt == 2)) {
-                rowStatus = (subAccount.getStatus() != null && subAccount.getStatus() == -1) ? -1
-                        : ((subAccount.getStatus() != null && subAccount.getStatus() == 2) || (subAccount.getLogoutFlag() != null && subAccount.getLogoutFlag() == 1)) ? 2
-                        : (subAccount.getStatus() != null ? subAccount.getStatus() : 0);
+                rowStatus = resolveLogoutRowStatus(subAccount);
             } else {
                 rowStatus = role.getStatus() != null ? role.getStatus() : (subAccount.getStatus() != null ? subAccount.getStatus() : 0);
             }
@@ -884,10 +907,11 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
             vo.setParentAccountPhone(mainAccount != null ? mainAccount.getPhone() : null);
             vo.setPhone(subAccount.getPhone());
             vo.setCreatedTime(subAccount.getCreatedTime() != null ? subAccount.getCreatedTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().format(formatter) : null);
-            int rowStatus = (subAccount.getStatus() != null && subAccount.getStatus() == -1) ? -1
-                    : ((subAccount.getStatus() != null && subAccount.getStatus() == 2) || (subAccount.getLogoutFlag() != null && subAccount.getLogoutFlag() == 1)) ? 2
-                    : (role.getStatus() != null ? role.getStatus() : (subAccount.getStatus() != null ? subAccount.getStatus() : 0));
-            vo.setStatus(rowStatus == -1 ? "注销中" : rowStatus == 2 ? "已注销" : (rowStatus == 0 ? "启用" : "禁用"));
+            int rowStatus = resolveLogoutRowStatus(subAccount);
+            if (statusInt == null || (statusInt != -1 && statusInt != 2)) {
+                rowStatus = role.getStatus() != null ? role.getStatus() : (subAccount.getStatus() != null ? subAccount.getStatus() : 0);
+            }
+            vo.setStatus(rowStatus == -1 ? "注销冷静期" : rowStatus == 2 ? "已注销" : (rowStatus == 0 ? "启用" : "禁用"));
             storeSubExcelVoList.add(vo);
         }
         String fileName = UUID.randomUUID().toString().replace("-", "");
@@ -984,13 +1008,15 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
         queryWrapper.eq(StoreUser::getPhone, phone)
                 .orderByDesc(StoreUser::getCreatedTime).last("LIMIT 1");
         StoreUser storeUser = storeUserMapper.selectOne(queryWrapper);
-        // 用户状态 0:启用,1:禁用,2:已注销
+        // 用户状态 0:启用,1:禁用;logout_flag 1:已注销,2:注销冷静期
         if (Objects.isNull(storeUser)) {
             return R.success("用户不存在,快去注册吧!");
-        } else if (storeUser.getStatus() == 1) {
+        } else if (storeUser.getStatus() != null && storeUser.getStatus() == 1) {
             return R.success("账号已被禁用");
-        } else if (storeUser.getStatus() == 2) {
+        } else if (isStoreUserLoggedOut(storeUser)) {
             return R.success("账号已注销");
+        } else if (isStoreUserLogoutCooling(storeUser)) {
+            return R.success("账号注销冷静期中");
         }
         return R.success("success");
     }
@@ -1025,16 +1051,17 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
         storeUserLambdaQueryWrapper.eq(StoreUser::getId, storeUserVo.getId());
         StoreUser storeUser = storeUserMapper.selectOne(storeUserLambdaQueryWrapper);
         if (storeUser != null) {
+            if (isStoreUserLogoutCooling(storeUser) || isStoreUserLoggedOut(storeUser)) {
+                throw new IllegalArgumentException("账号已在注销流程中");
+            }
             // 添加注销原因
             storeUser.setLogoutReason(storeUserVo.getLogoutReason());
             // 添加注销code
             storeUser.setLogoutCode(storeUserVo.getLogoutCode());
-            // 注销中状态
-            storeUser.setStatus(-1);
+            // 注销冷静期
+            storeUser.setLogoutFlag(StoreUser.LOGOUT_FLAG_COOLING);
             // 添加注销申请时间
             storeUser.setLogoutTime(new Date());
-            // 更新logout_flag状态为1
-            storeUser.setLogoutFlag(1);
             int num = storeUserMapper.updateById(storeUser);
             if (num > 0) {
                 // 发送通知
@@ -1042,7 +1069,7 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
                 lifeMessage.setReceiverId("store_" + storeUser.getPhone());
                 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                 String storeDate = simpleDateFormat.format(new Date());
-                String text = "您在" + storeDate + "注销了账号,平台将为您保留7天,在此期间您可撤销注销账号,7天后将会永久删除。";
+                String text = "您在" + storeDate + "注销了账号,平台将为您保留7天,在此期间您可撤销注销账号,7天后账号将变为已注销状态。";
                 com.alibaba.fastjson2.JSONObject jsonObject = new com.alibaba.fastjson2.JSONObject();
                 jsonObject.put("message", text);
                 lifeMessage.setContext(jsonObject.toJSONString());
@@ -1076,18 +1103,24 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
         LambdaQueryWrapper<StoreUser> storeUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
         storeUserLambdaQueryWrapper.eq(StoreUser::getId, storeUserVo.getId());
         StoreUser storeUser = storeUserMapper.selectOne(storeUserLambdaQueryWrapper);
+        if (storeUser == null) {
+            throw new IllegalArgumentException("账号不存在");
+        }
+        if (!isStoreUserLogoutCooling(storeUser)) {
+            throw new IllegalArgumentException("当前账号不在注销冷静期内,无法撤销");
+        }
         // 修改注销标记为0
-        storeUser.setLogoutFlag(0);
+        storeUser.setLogoutFlag(StoreUser.LOGOUT_FLAG_NORMAL);
         // 注销状态变为可用
-        storeUser.setStatus(0);
+        if (storeUser.getStatus() != null && storeUser.getStatus() == -1) {
+            storeUser.setStatus(0);
+        }
         // 清空注销原因
         storeUser.setLogoutReason("");
         // 清空注销code
         storeUser.setLogoutCode("");
         // 清空注销申请时间
         storeUser.setLogoutTime(null);
-        // 更新logout_flag状态为0
-        storeUser.setLogoutFlag(0);
         int num = storeUserMapper.updateById(storeUser);
         if (num > 0) {
             // 发送通知
@@ -1244,6 +1277,41 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
 
     }
 
+    /** 是否处于注销冷静期(含旧数据:status=-1 且 logout_flag=1) */
+    private static boolean isStoreUserLogoutCooling(StoreUser user) {
+        if (user == null || user.getLogoutFlag() == null) {
+            return Integer.valueOf(-1).equals(user != null ? user.getStatus() : null);
+        }
+        if (StoreUser.LOGOUT_FLAG_COOLING == user.getLogoutFlag()) {
+            return true;
+        }
+        return StoreUser.LOGOUT_FLAG_DONE == user.getLogoutFlag()
+                && Integer.valueOf(-1).equals(user.getStatus());
+    }
+
+    /** 是否已注销(logout_flag=1 且非旧冷静期数据) */
+    private static boolean isStoreUserLoggedOut(StoreUser user) {
+        if (user == null) {
+            return false;
+        }
+        if (StoreUser.LOGOUT_FLAG_DONE == user.getLogoutFlag()
+                && !Integer.valueOf(-1).equals(user.getStatus())) {
+            return true;
+        }
+        return Integer.valueOf(2).equals(user.getStatus());
+    }
+
+    /** 管理端展示:-1 冷静期,2 已注销 */
+    private static int resolveLogoutRowStatus(StoreUser user) {
+        if (isStoreUserLogoutCooling(user)) {
+            return -1;
+        }
+        if (isStoreUserLoggedOut(user)) {
+            return 2;
+        }
+        return user.getStatus() != null ? user.getStatus() : 0;
+    }
+
     /**
      * 安全解析字符串为整数
      */