Ver código fonte

删除冗余代码

lutong 3 semanas atrás
pai
commit
f2e6bc6938

+ 0 - 26
alien-dining/src/main/java/shop/alien/dining/annotation/OperationLog.java

@@ -1,26 +0,0 @@
-package shop.alien.dining.annotation;
-
-import java.lang.annotation.*;
-
-/**
- * 操作日志注解
- *
- * @author ssk
- * @version 1.0
- * @date 2024/12/4
- */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface OperationLog {
-    /**
-     * 操作描述
-     */
-    String value() default "";
-
-    /**
-     * 操作类型
-     */
-    String type() default "";
-}
-

+ 0 - 28
alien-dining/src/main/java/shop/alien/dining/aspect/OperationLogAspect.java

@@ -1,28 +0,0 @@
-package shop.alien.dining.aspect;
-
-import lombok.extern.slf4j.Slf4j;
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-import org.springframework.stereotype.Component;
-import shop.alien.dining.annotation.OperationLog;
-
-/**
- * 操作日志切面
- *
- * @author ssk
- * @version 1.0
- * @date 2024/12/4
- */
-@Slf4j
-@Aspect
-@Component
-public class OperationLogAspect {
-
-    @Before("@annotation(operationLog)")
-    public void before(JoinPoint joinPoint, OperationLog operationLog) {
-        // TODO: 实现操作日志记录逻辑
-        log.info("操作日志: {}", operationLog.value());
-    }
-}
-

+ 0 - 48
alien-dining/src/main/java/shop/alien/dining/enums/OrderStatus.java

@@ -1,48 +0,0 @@
-package shop.alien.dining.enums;
-
-/**
- * 订单状态枚举
- *
- * @author ssk
- * @version 1.0
- * @date 2024/12/4
- */
-public enum OrderStatus {
-    /**
-     * 待支付
-     */
-    PENDING_PAYMENT(0, "待支付"),
-    /**
-     * 已支付
-     */
-    PAID(1, "已支付"),
-    /**
-     * 制作中
-     */
-    PREPARING(2, "制作中"),
-    /**
-     * 已完成
-     */
-    COMPLETED(3, "已完成"),
-    /**
-     * 已取消
-     */
-    CANCELLED(4, "已取消");
-
-    private final Integer code;
-    private final String desc;
-
-    OrderStatus(Integer code, String desc) {
-        this.code = code;
-        this.desc = desc;
-    }
-
-    public Integer getCode() {
-        return code;
-    }
-
-    public String getDesc() {
-        return desc;
-    }
-}
-

+ 0 - 17
alien-dining/src/main/java/shop/alien/dining/feign/DiningServiceFeign.java

@@ -1,17 +0,0 @@
-package shop.alien.dining.feign;
-
-import org.springframework.cloud.openfeign.FeignClient;
-
-/**
- * 点餐服务Feign客户端
- * 用于调用其他微服务
- *
- * @author ssk
- * @version 1.0
- * @date 2024/12/4
- */
-@FeignClient(name = "dining-service", path = "/api")
-public interface DiningServiceFeign {
-    // TODO: 定义需要调用的其他服务接口
-}
-

+ 0 - 26
alien-dining/src/main/java/shop/alien/dining/listener/RedisKeyExpirationListener.java

@@ -1,26 +0,0 @@
-package shop.alien.dining.listener;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.redis.connection.Message;
-import org.springframework.data.redis.connection.MessageListener;
-import org.springframework.stereotype.Component;
-
-/**
- * Redis键过期监听器
- *
- * @author ssk
- * @version 1.0
- * @date 2024/12/4
- */
-@Slf4j
-@Component
-public class RedisKeyExpirationListener implements MessageListener {
-
-    @Override
-    public void onMessage(Message message, byte[] pattern) {
-        String expiredKey = message.toString();
-        log.info("Redis键过期: {}", expiredKey);
-        // TODO: 实现键过期后的业务逻辑
-    }
-}
-

+ 2 - 38
alien-store/src/main/java/shop/alien/store/controller/DiningUserController.java

@@ -10,7 +10,6 @@ import shop.alien.entity.result.R;
 import shop.alien.store.dto.ChangePhoneDto;
 import shop.alien.store.dto.UserProfileUpdateDto;
 import shop.alien.store.dto.VerifyTokenDto;
-import shop.alien.store.dto.WeChatLoginDto;
 import shop.alien.store.service.DiningUserService;
 import shop.alien.store.util.TokenUtil;
 import shop.alien.store.vo.DiningUserVo;
@@ -28,7 +27,7 @@ import javax.validation.Valid;
  * @date 2024/12/4
  */
 @Slf4j
-@Api(tags = {"微信点餐-登录(用户端)"})
+@Api(tags = {"点餐-用户资料(C  token,与网关登录一致)"})
 @ApiSort(2)
 @CrossOrigin
 @RestController
@@ -38,24 +37,6 @@ public class DiningUserController {
 
     private final DiningUserService diningUserService;
 
-    @ApiOperation(value = "微信小程序登录", notes = "标准流程:1. 前端调用 wx.login() 获取 code;2. 后端调用 jscode2session 获取 openid;3. 可选:通过 wx.getPhoneNumber() 获取 phoneCode 绑定手机号")
-    @PostMapping("/wechatLogin")
-    public R<DiningUserVo> wechatLogin(@Valid @RequestBody WeChatLoginDto loginDto, HttpServletRequest request) {
-        log.info("微信小程序登录: code={}, phoneCode={}",
-                loginDto.getCode(),
-                loginDto.getPhoneCode());
-
-        String macIp = getClientIp(request);
-        DiningUserVo userVo = diningUserService.wechatLogin(
-                loginDto.getCode(),
-                loginDto.getPhoneCode(),
-                macIp);
-        if (userVo == null) {
-            return R.fail("登录失败,请检查 code 是否有效(code 有效期5分钟,仅能使用一次)");
-        }
-        return R.data(userVo);
-    }
-
     @ApiOperation(value = "获取用户信息", notes = "获取当前登录用户的详细信息(从token中获取用户ID)")
     @GetMapping("/getUserInfo")
     public R<DiningUserVo> getUserInfo() {
@@ -114,7 +95,7 @@ public class DiningUserController {
         return R.data(userVo);
     }
 
-    @ApiOperation(value = "校验Token", notes = "验证Token是否有效,支持从请求头Authorization或请求体获取Token")
+    @ApiOperation(value = "校验Token", notes = "校验 C 端统一登录 JWT,并与 Redis key user_{手机号} 中缓存的 token 比对;支持从请求头 Authorization 或请求体传递")
     @PostMapping("/verifyToken")
     public R<TokenVerifyVo> verifyToken(@RequestBody(required = false) VerifyTokenDto dto, HttpServletRequest request) {
         // 优先从请求体获取 token,如果没有则从请求头获取
@@ -168,21 +149,4 @@ public class DiningUserController {
 
         return R.data(userInfo);
     }
-
-    /**
-     * 获取客户端IP地址
-     */
-    private String getClientIp(HttpServletRequest request) {
-        String ip = request.getHeader("X-Forwarded-For");
-        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
-            ip = request.getHeader("Proxy-Client-IP");
-        }
-        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
-            ip = request.getHeader("WL-Proxy-Client-IP");
-        }
-        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
-            ip = request.getRemoteAddr();
-        }
-        return ip;
-    }
 }

+ 0 - 29
alien-store/src/main/java/shop/alien/store/dto/WeChatLoginDto.java

@@ -1,29 +0,0 @@
-package shop.alien.store.dto;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-
-import javax.validation.constraints.NotBlank;
-
-/**
- * 微信小程序登录DTO
- * 标准流程:通过 wx.login() 获取 code,调用 jscode2session 获取 openid
- * 可选:通过 wx.getPhoneNumber() 获取 phoneCode,用于绑定手机号
- *
- * @author ssk
- * @version 2.0
- * @date 2024/12/4
- */
-@Data
-@ApiModel("微信小程序登录请求")
-public class WeChatLoginDto {
-
-    @ApiModelProperty(value = "微信登录凭证 code(通过 wx.login() 获取,必填)", required = true)
-    @NotBlank(message = "code不能为空,请通过 wx.login() 获取")
-    private String code;
-
-    @ApiModelProperty(value = "手机号凭证 code(通过 wx.getPhoneNumber() 获取,可选,用于绑定手机号)", required = false)
-    private String phoneCode;
-
-}

+ 0 - 10
alien-store/src/main/java/shop/alien/store/service/DiningUserService.java

@@ -15,16 +15,6 @@ import shop.alien.store.vo.TokenVerifyVo;
 public interface DiningUserService {
 
     /**
-     * 微信小程序登录(标准流程:通过 code2session 获取 openid)
-     *
-     * @param code      微信登录凭证(通过 wx.login() 获取,必填)
-     * @param phoneCode 手机号凭证(通过 wx.getPhoneNumber() 获取,可选)
-     * @param macIp     客户端IP地址
-     * @return 用户信息(包含 token)
-     */
-    DiningUserVo wechatLogin(String code, String phoneCode, String macIp);
-
-    /**
      * 更新用户个人信息
      *
      * @param dto 用户信息更新DTO

+ 19 - 398
alien-store/src/main/java/shop/alien/store/service/impl/DiningUserServiceImpl.java

@@ -6,7 +6,6 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import shop.alien.store.config.BaseRedisService;
@@ -15,11 +14,9 @@ import shop.alien.store.dto.UserProfileUpdateDto;
 import shop.alien.store.feign.AlienStoreFeign;
 import shop.alien.store.service.DiningUserService;
 import shop.alien.store.util.TokenUtil;
-import shop.alien.store.util.WeChatMiniProgramUtil;
-import shop.alien.store.util.WeChatMiniProgramUtil.WeChatSessionInfo;
-import shop.alien.entity.result.R;
 import shop.alien.store.vo.DiningUserVo;
 import shop.alien.store.vo.TokenVerifyVo;
+import shop.alien.entity.result.R;
 import shop.alien.entity.store.LifeUser;
 import shop.alien.mapper.LifeUserMapper;
 import shop.alien.util.common.JwtUtil;
@@ -29,16 +26,9 @@ import io.jsonwebtoken.MalformedJwtException;
 import io.jsonwebtoken.SignatureException;
 
 import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
 
 /**
- * 点餐用户服务实现类
- * 标准流程:通过 wx.login() 获取 code,调用 jscode2session 获取 openid
- *
- * @author ssk
- * @version 2.0
- * @date 2024/12/4
+ * 点餐用户服务:与 C 端 users 体系一致,登录发 token 由网关等原有链路完成;store 侧仅校验 {@code user_{phone}} Redis 与 JWT。
  */
 @Slf4j
 @Service
@@ -47,363 +37,28 @@ public class DiningUserServiceImpl implements DiningUserService {
 
     private final LifeUserMapper lifeUserMapper;
     private final BaseRedisService baseRedisService;
-    private final WeChatMiniProgramUtil weChatMiniProgramUtil;
     private final AlienStoreFeign alienStoreFeign;
 
-    @Value("${jwt.expiration-time}")
-    private String effectiveTime;
-
-    /**
-     * Redis key 常量(小程序专用,避免与 APP 端冲突)
-     */
-    private static final String REDIS_KEY_OPENID_PREFIX = "wechat:openid:";
-    private static final String REDIS_KEY_TOKEN_PREFIX = "miniprogram_user_token:";
-    private static final String REDIS_KEY_USER_PHONE_PREFIX = "miniprogram_user_";
-    private static final long OPENID_MAPPING_EXPIRE_SECONDS = 30 * 24 * 60 * 60L; // 30天
-    private static final long TOKEN_EXPIRE_SECONDS = 7 * 24 * 60 * 60L; // 7天
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public DiningUserVo wechatLogin(String code, String phoneCode, String macIp) {
-        // 1. 通过 code2session 获取 openid 和 session_key
-        String openid = getOpenidFromCode(code);
-        if (StringUtils.isBlank(openid)) {
-            return null;
-        }
-
-        // 2. 如果提供了 phoneCode,先解析手机号(用于返回给前端和更新用户)
-        String parsedPhone = null;
-        if (StringUtils.isNotBlank(phoneCode)) {
-            parsedPhone = weChatMiniProgramUtil.getPhoneNumberByCode(phoneCode);
-            if (StringUtils.isNotBlank(parsedPhone)) {
-                log.info("成功解析手机号: {}", maskString(parsedPhone, 7));
-            } else {
-                log.warn("解析手机号失败,phoneCode可能已过期或无效");
-            }
-        }
-        if (StringUtils.isBlank(parsedPhone)) {
-            log.info("微信登录未传手机号或解析失败: openid={}, phoneCode={}", maskString(openid, 8), StringUtils.isNotBlank(phoneCode) ? "已传" : "未传");
-        }
-
-        // 3. 查找或创建用户(传入解析后的手机号,避免重复解析)
-        LifeUser user = findOrCreateUser(openid, parsedPhone);
-        if (user == null) {
-            return null;
-        }
-
-        // 4. 检查用户状态(提前检查,避免不必要的操作)
-        if (!isUserValid(user)) {
-            return null;
-        }
-
-        // 5. 生成并存储 token(传入本次解析的手机号,确保有手机号时一定写入 miniprogram_user_{phone})
-        String token = generateAndStoreToken(openid, user, parsedPhone);
-
-        // 6. 构建返回对象,优先使用解析后的手机号返回给前端
-        return buildDiningUserVo(user, token, openid, parsedPhone);
-    }
-
-    /**
-     * 通过 code 获取 openid
-     */
-    private String getOpenidFromCode(String code) {
-        WeChatSessionInfo sessionInfo = weChatMiniProgramUtil.code2Session(code);
-        if (sessionInfo == null || sessionInfo.getErrcode() != null) {
-            Integer errcode = sessionInfo != null ? sessionInfo.getErrcode() : null;
-            String errmsg = sessionInfo != null ? sessionInfo.getErrmsg() : "调用微信接口失败";
-            log.error("登录失败:code2session 失败, errcode={}, errmsg={}", errcode, errmsg);
-            return null;
-        }
-
-        String openid = sessionInfo.getOpenid();
-        if (StringUtils.isBlank(openid)) {
-            log.error("登录失败:无法获取 openid");
-            return null;
-        }
-        log.info("成功获取 openid: {}", maskString(openid, 8));
-        return openid;
-    }
-
-    /**
-     * 查找或创建用户
-     * 规则:只要 user_phone 存在,就代表存在账号,不创建新账号
-     * 
-     * @param openid 微信OpenID
-     * @param phone 解析后的手机号(如果为null,说明没有提供phoneCode或解析失败)
-     */
-    private LifeUser findOrCreateUser(String openid, String phone) {
-        LifeUser user = null;
-        
-        // 1. 如果提供了手机号,优先通过手机号查找(只要手机号存在就代表账号存在)
-        if (StringUtils.isNotBlank(phone)) {
-            user = findUserByPhone(phone);
-            if (user != null) {
-                // 账号已存在,建立 openid 和 userId 的映射关系
-                saveOpenidMapping(openid, user.getId());
-                log.info("通过手机号找到已存在账号: phone={}, userId={}, openid={}", 
-                        maskString(phone, 7), user.getId(), maskString(openid, 8));
-                // 如果用户已有手机号,但新解析的手机号不同,更新手机号
-                if (StringUtils.isNotBlank(user.getUserPhone()) && !user.getUserPhone().equals(phone)) {
-                    log.info("检测到手机号变更,更新手机号: userId={}, oldPhone={}, newPhone={}", 
-                            user.getId(), maskString(user.getUserPhone(), 7), maskString(phone, 7));
-                    updateUserPhone(user, phone);
-                }
-                return user;
-            }
-        }
-        
-        // 2. 如果通过手机号找不到(或未提供手机号),尝试通过 openid 查找
-        user = findUserByOpenid(openid);
-        
-        // 3. 如果通过 openid 找到了用户,且提供了手机号,更新手机号
-        if (user != null) {
-            if (StringUtils.isNotBlank(phone) && StringUtils.isBlank(user.getUserPhone())) {
-                // 用户存在但没有手机号,更新手机号
-                updateUserPhone(user, phone);
-            } else if (StringUtils.isNotBlank(phone) && StringUtils.isNotBlank(user.getUserPhone()) 
-                    && !user.getUserPhone().equals(phone)) {
-                // 用户已有手机号,但新解析的手机号不同,也更新
-                log.info("检测到手机号变更,更新手机号: userId={}, oldPhone={}, newPhone={}", 
-                        user.getId(), maskString(user.getUserPhone(), 7), maskString(phone, 7));
-                updateUserPhone(user, phone);
-            }
-            return user;
-        }
-
-        // 4. 如果都找不到,且未提供手机号(或手机号不存在),才创建新账号
-        // 注意:如果提供了手机号但找不到,说明这个手机号没有注册过,可以创建新账号
-        user = createNewUser(openid, phone);
-        if (user != null) {
-            saveOpenidMapping(openid, user.getId());
-        }
-
-        return user;
-    }
-
-    /**
-     * 通过 openid 查找用户
-     */
-    private LifeUser findUserByOpenid(String openid) {
-        String openidKey = REDIS_KEY_OPENID_PREFIX + openid;
-        String userIdStr = baseRedisService.getString(openidKey);
-        
-        if (StringUtils.isBlank(userIdStr)) {
-            return null;
-        }
-
-        try {
-            Integer userId = Integer.parseInt(userIdStr);
-            LifeUser user = lifeUserMapper.selectById(userId);
-            if (user != null) {
-                log.info("通过 openid 找到用户: openid={}, userId={}", maskString(openid, 8), userId);
-            }
-            return user;
-        } catch (NumberFormatException e) {
-            log.warn("Redis 中的 userId 格式错误: {}", userIdStr);
-            return null;
-        }
-    }
-
-    /**
-     * 通过手机号查找用户
-     */
-    private LifeUser findUserByPhone(String phone) {
-        LambdaQueryWrapper<LifeUser> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(LifeUser::getUserPhone, phone);
-        LifeUser user = lifeUserMapper.selectOne(queryWrapper);
-        if (user != null) {
-            log.info("通过手机号找到用户: phone={}, userId={}", maskString(phone, 7), user.getId());
-        }
-        return user;
-    }
-
-    /**
-     * 创建新用户
-     */
-    private LifeUser createNewUser(String openid, String phone) {
-        LifeUser user = new LifeUser();
-        if (StringUtils.isNotBlank(phone)) {
-            user.setUserPhone(phone);
-            user.setUserName(phone);
-            user.setRealName(phone);
-        } else {
-            // 没有手机号时,使用 openid 后8位作为临时用户名
-            String tempName = "微信用户" + openid.substring(Math.max(0, openid.length() - 8));
-            user.setUserName(tempName);
-            user.setRealName(tempName);
-        }
-        user.setCreatedTime(new Date());
-        
-        int ret = lifeUserMapper.insert(user);
-        if (ret != 1) {
-            log.error("创建用户失败");
-            return null;
-        }
-        
-        // MyBatis-Plus 的 insert 会自动填充 ID,不需要重新查询
-        log.info("创建新用户: openid={}, userId={}, phone={}", maskString(openid, 8), user.getId(), maskString(phone, 7));
-        return user;
-    }
-
-    /**
-     * 更新用户手机号
-     */
-    private void updateUserPhone(LifeUser user, String phone) {
-        user.setUserPhone(phone);
-        if (StringUtils.isBlank(user.getUserName()) || user.getUserName().startsWith("微信用户")) {
-            user.setUserName(phone);
-        }
-        if (StringUtils.isBlank(user.getRealName()) || user.getRealName().startsWith("微信用户")) {
-            user.setRealName(phone);
-        }
-        user.setUpdatedTime(new Date());
-        lifeUserMapper.updateById(user);
-        log.info("更新用户手机号: userId={}, phone={}", user.getId(), maskString(phone, 7));
-    }
-
-    /**
-     * 保存 openid 和 userId 的映射关系
-     */
-    private void saveOpenidMapping(String openid, Integer userId) {
-        String openidKey = REDIS_KEY_OPENID_PREFIX + openid;
-        baseRedisService.setString(openidKey, userId.toString(), OPENID_MAPPING_EXPIRE_SECONDS);
-    }
-
-    /**
-     * 检查用户状态是否有效
-     */
-    private boolean isUserValid(LifeUser user) {
-        if (user.getIsBanned() != null && user.getIsBanned() == 1) {
-            log.warn("用户已被封禁: userId={}", user.getId());
-            return false;
-        }
-        if (user.getLogoutFlag() != null && user.getLogoutFlag() == 1) {
-            log.warn("用户已注销: userId={}", user.getId());
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * 生成并存储 token
-     * @param openid 微信 openid
-     * @param user 用户实体(可能尚未持久化手机号)
-     * @param currentLoginPhone 本次登录解析到的手机号(可选),有则优先用其写入 miniprogram_user_{phone},避免只存 openid 不存 phone 的情况
-     */
-    private String generateAndStoreToken(String openid, LifeUser user, String currentLoginPhone) {
-        // 构建 token 信息
-        Map<String, String> tokenMap = buildTokenMap(openid, user);
-        String userName = StringUtils.isNotBlank(user.getUserName()) ? user.getUserName() : "用户";
-        String token = generateToken(openid, userName, tokenMap);
-
-        // 存入 Redis(使用 openid 作为 key,始终写入)
-        baseRedisService.setString(REDIS_KEY_TOKEN_PREFIX + openid, token, TOKEN_EXPIRE_SECONDS);
-
-        // 兼容旧版本:有手机号则同时按手机号存一份(优先用本次登录解析到的手机号,否则用用户实体中的手机号)
-        String phoneToStore = StringUtils.isNotBlank(currentLoginPhone) ? currentLoginPhone : user.getUserPhone();
-        if (StringUtils.isNotBlank(phoneToStore)) {
-            baseRedisService.setString(REDIS_KEY_USER_PHONE_PREFIX + phoneToStore, token, TOKEN_EXPIRE_SECONDS);
-        }
-
-        return token;
-    }
-
-    /**
-     * 构建 token 信息 Map
-     */
-    private Map<String, String> buildTokenMap(String openid, LifeUser user) {
-        Map<String, String> tokenMap = new HashMap<>();
-        tokenMap.put("openid", openid);
-        tokenMap.put("phone", StringUtils.isNotBlank(user.getUserPhone()) ? user.getUserPhone() : "");
-        tokenMap.put("userName", StringUtils.isNotBlank(user.getUserName()) ? user.getUserName() : "用户");
-        tokenMap.put("userId", user.getId().toString());
-        tokenMap.put("userType", "miniprogram_user");
-        return tokenMap;
-    }
-
-    /**
-     * 构建返回对象
-     */
-    private DiningUserVo buildDiningUserVo(LifeUser user, String token, String openid) {
-        DiningUserVo diningUserVo = new DiningUserVo();
-        diningUserVo.setId(user.getId().longValue());
-        // 优先使用 user 对象中的手机号(如果通过 phoneCode 解析并更新了,这里会是最新的)
-        diningUserVo.setPhone(user.getUserPhone());
-        diningUserVo.setNickName(user.getUserName());
-        diningUserVo.setAvatarUrl(user.getUserImage());
-        diningUserVo.setStatus(0);
-        diningUserVo.setCreatedTime(user.getCreatedTime());
-        diningUserVo.setToken(token);
-        diningUserVo.setOpenId(openid);
-        return diningUserVo;
-    }
-    
-    /**
-     * 构建返回对象(带解析后的手机号)
-     */
-    private DiningUserVo buildDiningUserVo(LifeUser user, String token, String openid, String parsedPhone) {
-        DiningUserVo diningUserVo = buildDiningUserVo(user, token, openid);
-        // 如果解析到了手机号,优先使用解析后的手机号返回给前端
-        if (StringUtils.isNotBlank(parsedPhone)) {
-            diningUserVo.setPhone(parsedPhone);
-        }
-        return diningUserVo;
-    }
-
-    /**
-     * 掩码字符串(用于日志脱敏)
-     */
-    private String maskString(String str, int visibleLength) {
-        if (StringUtils.isBlank(str) || str.length() <= visibleLength) {
-            return "****";
-        }
-        return str.substring(0, Math.min(visibleLength, str.length())) + "****";
-    }
-
-    private String generateToken(String userId, String userName, Map<String, String> tokenMap) {
-        int effectiveTimeInt = Integer.parseInt(effectiveTime.substring(0, effectiveTime.length() - 1));
-        String effectiveTimeUnit = effectiveTime.substring(effectiveTime.length() - 1);
-        long effectiveTimeIntLong = 0L;
-        switch (effectiveTimeUnit) {
-            case "s":
-                effectiveTimeIntLong = effectiveTimeInt * 1000L;
-                break;
-            case "m":
-                effectiveTimeIntLong = effectiveTimeInt * 60L * 1000L;
-                break;
-            case "h":
-                effectiveTimeIntLong = effectiveTimeInt * 60L * 60L * 1000L;
-                break;
-            case "d":
-                effectiveTimeIntLong = effectiveTimeInt * 24L * 60L * 60L * 1000L;
-                break;
-            default:
-                effectiveTimeIntLong = effectiveTimeInt * 24L * 60L * 60L * 1000L;
-        }
-        return JwtUtil.createJWT("user_" + userId, userName, JSONObject.toJSONString(tokenMap), effectiveTimeIntLong);
-    }
+    /** 与网关 {@code LifeUserService#userLogin} 写入 Redis 的 key 一致:{@code user_} + 手机号 */
+    private static final String REDIS_USER_TOKEN_PREFIX = "user_";
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public DiningUserVo updateProfile(UserProfileUpdateDto dto) {
-        // 1. 查询用户是否存在
         LifeUser user = lifeUserMapper.selectById(dto.getUserId().intValue());
         if (user == null) {
             log.warn("更新个人信息失败:用户不存在, userId={}", dto.getUserId());
             return null;
         }
 
-        // 2. 获取当前用户ID(用于设置 updatedUserId)
         Integer currentUserId = TokenUtil.getCurrentUserId();
         if (currentUserId == null) {
-            currentUserId = dto.getUserId().intValue(); // 如果没有 token,使用被更新的用户ID
+            currentUserId = dto.getUserId().intValue();
         }
 
-        // 3. 使用 LambdaUpdateWrapper 只更新需要更新的字段,避免更新不应该更新的字段
         LambdaUpdateWrapper<LifeUser> updateWrapper = new LambdaUpdateWrapper<>();
         updateWrapper.eq(LifeUser::getId, dto.getUserId().intValue());
 
-        // 只更新非空字段
         if (StringUtils.isNotBlank(dto.getNickName())) {
             updateWrapper.set(LifeUser::getUserName, dto.getNickName());
         }
@@ -435,11 +90,9 @@ public class DiningUserServiceImpl implements DiningUserService {
             updateWrapper.set(LifeUser::getJianjie, dto.getJianjie());
         }
 
-        // 设置更新时间和更新人ID
         updateWrapper.set(LifeUser::getUpdatedTime, new Date());
         updateWrapper.set(LifeUser::getUpdatedUserId, currentUserId);
 
-        // 4. 执行更新
         int result = lifeUserMapper.update(null, updateWrapper);
         if (result != 1) {
             log.error("更新用户信息失败, userId={}", dto.getUserId());
@@ -447,27 +100,23 @@ public class DiningUserServiceImpl implements DiningUserService {
         }
         log.info("用户信息更新成功, userId={}, updatedUserId={}", dto.getUserId(), currentUserId);
 
-        // 5. 重新查询用户信息(因为使用 updateWrapper 后,user 对象不会自动更新)
         LifeUser updatedUser = lifeUserMapper.selectById(dto.getUserId().intValue());
         if (updatedUser == null) {
             log.error("更新后查询用户信息失败, userId={}", dto.getUserId());
             return null;
         }
 
-        // 6. 返回更新后的用户信息
         return buildDiningUserVo(updatedUser);
     }
 
     @Override
     public DiningUserVo getUserInfo(Long userId) {
-        // 1. 查询用户
         LifeUser user = lifeUserMapper.selectById(userId.intValue());
         if (user == null) {
             log.warn("获取用户信息失败:用户不存在, userId={}", userId);
             return null;
         }
 
-        // 2. 检查用户状态
         if (user.getIsBanned() != null && user.getIsBanned() == 1) {
             log.warn("用户已被封禁: userId={}", userId);
             return null;
@@ -477,7 +126,6 @@ public class DiningUserServiceImpl implements DiningUserService {
             return null;
         }
 
-        // 3. 返回用户信息
         return buildDiningUserVo(user);
     }
 
@@ -487,7 +135,6 @@ public class DiningUserServiceImpl implements DiningUserService {
         String newPhone = dto.getNewPhone().trim();
         String codeStr = dto.getCode().trim();
 
-        // 1. 校验验证码(Feign 调 store ali/checkSmsCode,appType=0 用户端,businessType=3 修改手机号)
         int codeInt;
         try {
             codeInt = Integer.parseInt(codeStr);
@@ -501,7 +148,6 @@ public class DiningUserServiceImpl implements DiningUserService {
             return null;
         }
 
-        // 2. 查询用户
         LifeUser user = lifeUserMapper.selectById(dto.getUserId().intValue());
         if (user == null) {
             log.warn("更换手机号失败:用户不存在, userId={}", dto.getUserId());
@@ -516,13 +162,11 @@ public class DiningUserServiceImpl implements DiningUserService {
             return null;
         }
 
-        // 3. 新手机号与当前相同则无需更新
         if (newPhone.equals(user.getUserPhone())) {
             log.info("新手机号与当前相同,无需更换, userId={}", dto.getUserId());
             return buildDiningUserVo(user);
         }
 
-        // 4. 新手机号是否已被其他用户使用
         LambdaQueryWrapper<LifeUser> q = new LambdaQueryWrapper<>();
         q.eq(LifeUser::getUserPhone, newPhone);
         LifeUser existing = lifeUserMapper.selectOne(q);
@@ -531,7 +175,6 @@ public class DiningUserServiceImpl implements DiningUserService {
             return null;
         }
 
-        // 5. 更新 user_phone
         String oldPhone = user.getUserPhone();
         user.setUserPhone(newPhone);
         user.setUpdatedTime(new Date());
@@ -541,10 +184,11 @@ public class DiningUserServiceImpl implements DiningUserService {
             return null;
         }
 
-        // 6. 只清除小程序旧手机号对应的 token,APP 的 token 保持不变
-        // 因为小程序更换手机号只影响小程序平台,APP 可以继续使用旧手机号登录
-        baseRedisService.delete(REDIS_KEY_USER_PHONE_PREFIX + oldPhone);
-        log.info("更换手机号成功, userId={}, oldPhone={}, newPhone={}(仅清除小程序 token,APP token 保持不变)", dto.getUserId(), oldPhone, newPhone);
+        if (StringUtils.isNotBlank(oldPhone)) {
+            baseRedisService.delete(REDIS_USER_TOKEN_PREFIX + oldPhone);
+        }
+        log.info("更换手机号成功, userId={}, oldPhone={}, newPhone={}(已清除 C 端 Redis token,需重新登录)",
+                dto.getUserId(), oldPhone, newPhone);
 
         return buildDiningUserVo(user);
     }
@@ -554,28 +198,24 @@ public class DiningUserServiceImpl implements DiningUserService {
         TokenVerifyVo verifyVo = new TokenVerifyVo();
         verifyVo.setValid(false);
 
-        // 1. 检查 token 是否为空
         if (StringUtils.isBlank(token)) {
             verifyVo.setReason("Token 不能为空");
             return verifyVo;
         }
 
-        // 去除 "Bearer " 前缀(不区分大小写)
         token = token.trim();
         if (token.length() > 7 && token.substring(0, 7).equalsIgnoreCase("Bearer ")) {
             token = token.substring(7).trim();
         }
-        
+
         if (StringUtils.isBlank(token)) {
             verifyVo.setReason("Token 去除前缀后为空");
             return verifyVo;
         }
 
         try {
-            // 2. 解析 token,验证格式和签名
             Claims claims = JwtUtil.parseJWT(token);
-            
-            // 3. 检查 token 是否过期
+
             Date expiration = claims.getExpiration();
             if (expiration != null && expiration.before(new Date())) {
                 verifyVo.setReason("Token 已过期");
@@ -583,38 +223,24 @@ public class DiningUserServiceImpl implements DiningUserService {
                 return verifyVo;
             }
 
-            // 4. 从 token 中提取用户信息
             String sub = claims.get("sub").toString();
             JSONObject tokenInfo = JSONObject.parseObject(sub);
-            String openid = tokenInfo.getString("openid");
             String phone = tokenInfo.getString("phone");
             String userIdStr = tokenInfo.getString("userId");
             String userName = tokenInfo.getString("userName");
+            String openid = tokenInfo.getString("openid");
 
-            // 5. 验证 Redis 中是否存在该 token(使用小程序专用的 key 前缀)
-            boolean tokenExists = false;
-            if (StringUtils.isNotBlank(openid)) {
-                // 优先使用 openid 查找
-                String redisToken = baseRedisService.getString(REDIS_KEY_TOKEN_PREFIX + openid);
-                if (token.equals(redisToken)) {
-                    tokenExists = true;
-                }
-            }
-            
-            // 兼容旧版本:通过手机号查找
-            if (!tokenExists && StringUtils.isNotBlank(phone)) {
-                String redisToken = baseRedisService.getString(REDIS_KEY_USER_PHONE_PREFIX + phone);
-                if (token.equals(redisToken)) {
-                    tokenExists = true;
-                }
+            if (StringUtils.isBlank(phone)) {
+                verifyVo.setReason("Token 中无手机号,请使用 C 端统一登录获取 token");
+                return verifyVo;
             }
 
-            if (!tokenExists) {
+            String redisToken = baseRedisService.getString(REDIS_USER_TOKEN_PREFIX + phone);
+            if (!token.equals(redisToken)) {
                 verifyVo.setReason("Token 不存在或已失效(可能已退出登录)");
                 return verifyVo;
             }
 
-            // 6. 验证用户状态(如果提供了 userId)
             if (StringUtils.isNotBlank(userIdStr)) {
                 try {
                     Integer userId = Integer.parseInt(userIdStr);
@@ -636,7 +262,6 @@ public class DiningUserServiceImpl implements DiningUserService {
                 }
             }
 
-            // 7. Token 验证通过,返回用户信息
             verifyVo.setValid(true);
             if (StringUtils.isNotBlank(userIdStr)) {
                 try {
@@ -650,7 +275,7 @@ public class DiningUserServiceImpl implements DiningUserService {
             verifyVo.setOpenid(openid);
             verifyVo.setExpirationTime(expiration);
 
-            log.info("Token 验证成功: userId={}, openid={}, phone={}", userIdStr, openid, phone);
+            log.info("Token 验证成功: userId={}, phone={}", userIdStr, phone);
             return verifyVo;
 
         } catch (ExpiredJwtException e) {
@@ -672,9 +297,6 @@ public class DiningUserServiceImpl implements DiningUserService {
         }
     }
 
-    /**
-     * 构建 DiningUserVo
-     */
     private DiningUserVo buildDiningUserVo(LifeUser user) {
         DiningUserVo diningUserVo = new DiningUserVo();
         diningUserVo.setId(user.getId().longValue());
@@ -683,7 +305,6 @@ public class DiningUserServiceImpl implements DiningUserService {
         diningUserVo.setAvatarUrl(user.getUserImage());
         diningUserVo.setStatus(0);
         diningUserVo.setCreatedTime(user.getCreatedTime());
-        // 补充更多字段
         diningUserVo.setGender(user.getUserSex());
         diningUserVo.setBirthday(user.getUserBirthday());
         diningUserVo.setRealName(user.getRealName());