You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用NestJS结合TypeORM时无法更新isTokenExpired字段的技术求助

解决isExpired字段更新失败的问题

我帮你梳理下代码里可能存在的问题,以及对应的修复方案:


1. 控制器参数接收错误(最可能的原因)

你的控制器里直接用@Body() isExpired: boolean接收参数,但如果前端是通过JSON格式发送请求(比如{"isExpired": false}),这种写法会把整个请求体赋值给isExpired,导致它变成一个对象而非布尔值,最终传给Service的参数完全不符合预期。

修复后的控制器代码:

@Put('updateToken/:accessToken')
async updateExpiryStatus(
  @Param('accessToken') accessToken: string,
  @Body() body: { isExpired: boolean } // 改为接收包含字段的对象
): Promise<string> {
  const result = await this.passwordService.updateExpiryStatus(accessToken, body.isExpired);
  // 根据更新结果返回明确提示
  return result.affected > 0 ? "状态更新成功" : "未找到对应Token或无变更";
}

2. Service层的更新逻辑优化

你当前用了createQueryBuilder做更新,虽然语法没问题,但可以加一些校验和更直观的写法,同时排查更新失败的根因:

方案一:改用TypeORM的save方法(更简洁易维护)

async updateExpiryStatus(
  accessToken: string,
  isExpired: boolean
): Promise<any> {
  // 先确认Token对应的记录存在
  const expiryRecord = await this.passwordRepository.findOne({
    where: { accessToken },
  });

  if (!expiryRecord) {
    throw new Error("未找到该Token对应的密码重置记录");
  }

  // 修改字段后保存
  expiryRecord.isExpired = isExpired;
  const updatedRecord = await this.passwordRepository.save(expiryRecord);
  
  console.log('更新日志:', {
    originalStatus: expiryRecord.isExpired,
    newStatus: updatedRecord.isExpired,
    accessToken
  });
  
  return { affected: 1, updatedRecord }; // 对齐QueryBuilder的返回格式
}

方案二:保留QueryBuilder但增强校验

如果你坚持用QueryBuilder,建议先校验记录是否存在,同时打印更新结果的详细信息:

async updateExpiryStatus(
  accessToken: string,
  isExpired: boolean
): Promise<any> {
  const expiryRecord = await this.passwordRepository.findOne({
    where: { accessToken },
  });

  if (!expiryRecord) {
    throw new Error("未找到该Token对应的密码重置记录");
  }

  const result = await this.passwordRepository
    .createQueryBuilder('password_entity')
    .update(PasswordEntity)
    .set({ isExpired })
    .where('accessToken = :accessToken', { accessToken })
    .execute();
  
  console.log('更新结果:', {
    matchedRecord: expiryRecord,
    accessToken,
    isExpired,
    affectedRows: result.affected
  });
  
  return result;
}

3. 关键排查步骤

  • 查看控制台日志里的expiryStatus是否有值:如果为undefined,说明前端传的accessToken和数据库里的记录不匹配(注意URL参数的特殊字符转义、大小写问题)
  • 查看result.affected的值:如果是0,说明更新语句没有匹配到任何记录;如果是1,说明更新成功,可能是前端没有拉取最新数据导致误以为没更新
  • 确认数据库表字段:实体里的isExpired字段,TypeORM默认会映射为数据库的is_expired(蛇形命名),如果手动修改过表字段名,需要保证和实体定义一致

内容的提问来源于stack exchange,提问作者Abubakar Oluyinka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 10:37:33