使用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
相关产品推荐
相关产品推荐

