Jelajahi Sumber

注册修改

zhangchen 4 jam lalu
induk
melakukan
0b9c8e5268

+ 9 - 0
alien-entity/src/main/java/shop/alien/entity/store/LifeUser.java

@@ -25,6 +25,15 @@ import java.util.Date;
 public class LifeUser implements Serializable {
     private static final long serialVersionUID = 1L;
 
+    /** 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;
+    /** 注销完成后禁止重新注册的天数(自 logoutTime 日起,T+14 00:00 起可注册) */
+    public static final int RE_REGISTER_BLOCK_DAYS = 14;
+
     @ApiModelProperty(value = "主键")
     @TableId(value = "id", type = IdType.AUTO)
     private Integer id;

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

@@ -42,6 +42,10 @@ public class LifeUserController {
                                    @RequestParam(value = "macIp", required = false) String macIp,
                                    @RequestParam(value = "inviteCode", required = false) String inviteCode) {
         log.info("LifeUserController.userLogin?phoneNum={}&code={}", phoneNum, code);
+        String reRegisterBlockedMessage = lifeUserService.getReRegisterBlockedMessage(phoneNum);
+        if (reRegisterBlockedMessage != null) {
+            return R.fail(reRegisterBlockedMessage);
+        }
         LifeUserVo userVo = lifeUserService.userLogin(phoneNum, inviteCode, macIp);
         if (null == userVo) {
             return R.fail("登录失败");

+ 8 - 0
alien-gateway/src/main/java/shop/alien/gateway/mapper/LifeUserGatewayMapper.java

@@ -2,6 +2,8 @@ package shop.alien.gateway.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 import shop.alien.entity.store.LifeUser;
 
 /**
@@ -10,4 +12,10 @@ import shop.alien.entity.store.LifeUser;
 @Mapper
 public interface LifeUserGatewayMapper extends BaseMapper<LifeUser> {
 
+    /**
+     * 查询已逻辑删除且已注销的用户(绕过 {@link LifeUser#deleteFlag} 的 TableLogic 过滤)。
+     */
+    @Select("SELECT * FROM life_user WHERE user_phone = #{phoneNum} AND delete_flag = 1 AND logout_flag = 1 LIMIT 1")
+    LifeUser selectCancelledDeletedByPhone(@Param("phoneNum") String phoneNum);
+
 }

+ 53 - 0
alien-gateway/src/main/java/shop/alien/gateway/service/LifeUserService.java

@@ -2,6 +2,7 @@ package shop.alien.gateway.service;
 
 import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import org.apache.commons.lang3.StringUtils;
@@ -70,6 +71,7 @@ public class LifeUserService extends ServiceImpl<LifeUserGatewayMapper, LifeUser
     private String effectiveTime;
 
     private static final DateTimeFormatter LOGOUT_END_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy/MM/dd");
+    private static final DateTimeFormatter RE_REGISTER_ALLOW_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
 
     /**
      * 申请注销结束时间:logoutTime 起算第 7 天(T+0~T+7),与定时任务冷静期一致。
@@ -92,6 +94,54 @@ public class LifeUserService extends ServiceImpl<LifeUserGatewayMapper, LifeUser
         userVo.setLogoutEndTime(resolveLogoutEndTime(user.getLogoutTime(), user.getLogoutFlag()));
     }
 
+    /**
+     * 注销完成日 T(logoutTime)起,至 T+{@link LifeUser#RE_REGISTER_BLOCK_DAYS} 日 00:00 前禁止重新注册/登录。
+     */
+    public static boolean isWithinReRegisterBlockPeriod(Date logoutTime) {
+        if (logoutTime == null) {
+            return false;
+        }
+        ZoneId zone = ZoneId.systemDefault();
+        LocalDateTime allowFrom = logoutTime.toInstant()
+                .atZone(zone)
+                .toLocalDate()
+                .plusDays(LifeUser.RE_REGISTER_BLOCK_DAYS)
+                .atStartOfDay();
+        return LocalDateTime.now(zone).isBefore(allowFrom);
+    }
+
+    /**
+     * 可重新注册时间:logoutTime 对应日 T 的 T+14 日 00:00。
+     */
+    public static String resolveReRegisterAllowTime(Date logoutTime) {
+        if (logoutTime == null) {
+            return null;
+        }
+        return logoutTime.toInstant()
+                .atZone(ZoneId.systemDefault())
+                .toLocalDate()
+                .plusDays(LifeUser.RE_REGISTER_BLOCK_DAYS)
+                .atStartOfDay()
+                .format(RE_REGISTER_ALLOW_TIME_FORMAT);
+    }
+
+    /**
+     * 手机号处于注销禁登期时返回完整提示,否则返回 null。
+     */
+    public String getReRegisterBlockedMessage(String phoneNum) {
+        LifeUser user = getUserByPhoneDelete(phoneNum);
+        if (user == null
+                || LifeUser.LOGOUT_FLAG_DONE != user.getLogoutFlag()
+                || !isWithinReRegisterBlockPeriod(user.getLogoutTime())) {
+            return null;
+        }
+        String allowTime = resolveReRegisterAllowTime(user.getLogoutTime());
+        if (allowTime == null) {
+            return null;
+        }
+        return "原手机号无法注册新账号," + allowTime + "起,原手机号可重新注册";
+    }
+
     public LifeUserVo userLogin(String phoneNum, String inviteCode, String macIp) {
         LifeUser user = getUserByPhone(phoneNum);
         if (user == null) {
@@ -189,6 +239,9 @@ public class LifeUserService extends ServiceImpl<LifeUserGatewayMapper, LifeUser
         return this.getOne(lambdaQueryWrapper);
     }
 
+    public LifeUser getUserByPhoneDelete(String phoneNum) {
+        return lifeUserMapper.selectCancelledDeletedByPhone(phoneNum);
+    }
 
     /**
      * 用户登录log存放(加入mac地址)

+ 10 - 5
alien-job/src/main/java/shop/alien/job/store/StoreMembershipCardJob.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.xxl.job.core.handler.annotation.XxlJob;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Component;
 import shop.alien.config.redis.BaseRedisService;
 import shop.alien.entity.store.*;
@@ -246,8 +247,9 @@ public class StoreMembershipCardJob {
             }
         }
 
-        // 获取全部申请注销的用户
-        List<LifeUser> lifeUsers = lifeUserMapper.selectList(new LambdaQueryWrapper<LifeUser>().eq(LifeUser::getLogoutFlag, LOGOUT_FLAG_COOLING));
+        // 获取处于注销冷静期的 C 端用户
+        List<LifeUser> lifeUsers = lifeUserMapper.selectList(
+                new LambdaQueryWrapper<LifeUser>().eq(LifeUser::getLogoutFlag, LifeUser.LOGOUT_FLAG_COOLING));
         for (LifeUser lifeUser : lifeUsers) {
             try {
                 if (null != lifeUser.getLogoutTime()) {
@@ -261,14 +263,17 @@ public class StoreMembershipCardJob {
                     // 获取当前时间
                     Date date = new Date();
                     if (date.compareTo(sevenDay) >= 0) {
-                        // 删除已过注销时间的用户
-                        lifeUserMapper.deleteById(lifeUser.getId());
+                        LifeUser update = new LifeUser();
+                        update.setId(lifeUser.getId());
+                        update.setLogoutFlag(LifeUser.LOGOUT_FLAG_DONE);
+                        update.setDeleteFlag(1);
+                        lifeUserMapper.updateById(update);
                         successCount++;
                     }
                 }
             } catch (Exception e) {
                 failCount++;
-                log.error("删除用户失败: userId={}, phone={}, error={}", 
+                log.error("C端用户注销状态更新失败: userId={}, phone={}, error={}",
                         lifeUser.getId(), lifeUser.getUserPhone(), e.getMessage(), e);
             }
         }