Node.js考勤系统OPID7用户查询返回负工时其余用户正常故障排查
问题根因定位
- 核心问题:当日打卡记录查询未指定排序规则。你在
/clock/:id路由中查询用户当日打卡记录的SQL没有加ORDER BY DATETIME ASC,Firebird数据库不指定排序时默认按存储顺序返回结果,OPID 7的打卡记录存储顺序恰好和时间升序相反,导致两两配对计算时长时,后一条记录的时间早于前一条,差值为负数。其余用户的记录存储顺序刚好和时间顺序一致,所以计算结果正常。 - 次要隐患:当前
break-out和clock-out接口写入的打卡类型ETXNTTYPE均为1,没有区分下班和休息事件,后续如果要做休息时长扣除逻辑会出错,但本次负数问题与此无关。 - 额外风险:代码中所有SQL均直接拼接
req.params.id参数,存在严重SQL注入漏洞,建议尽快修复。
修复方案
- 优先修改当日打卡查询SQL,增加排序规则:
将原查询语句
SELECT FIRST 10 * FROM TXATTENDETXNTS WHERE OPID = ' + req.params.id + ' AND DATETIME >= \'' + moment().startOf('day').format('YYYY-MM-DD HH:mm:ss') + '\'
修改为
SELECT FIRST 10 * FROM TXATTENDETXNTS WHERE OPID = ' + req.params.id + ' AND DATETIME >= \'' + moment().startOf('day').format('YYYY-MM-DD HH:mm:ss') + '\' ORDER BY DATETIME ASC
- 可增加容错逻辑避免极端情况出现负数:
将时长计算代码修改为取绝对值:
totalMinutes += Math.abs(Math.round(moment.duration(moment(pair[1].DATETIME).diff(moment(pair[0].DATETIME))).asMinutes()));
- 长期修复建议改用参数化查询,避免SQL注入风险。
内容的提问来源于stack exchange,提问作者daneee
相关产品推荐
相关产品推荐

