GetInfo 添加获取年龄#70
Conversation
PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
||||||||||||||||||||||||
Walkthrough新增一个非导出年龄计算辅助函数并引入 Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 诗
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
PR Code Suggestions ✨Explore these optional code suggestions:
|
||||||||||||
Review Summary by QodoAdd age calculation and supplement address code data
WalkthroughsDescription• Add age calculation feature to ID card information retrieval • Supplement historical address code data for multiple provinces • Expand address code coverage for Hong Kong, Macau, and Taiwan regions • Fix address code timeline data inconsistencies and formatting Diagramflowchart LR
A["ID Validator"] -->|"Parse ID"| B["Generate Code"]
B -->|"Extract Birthday"| C["Calculate Age"]
C -->|"Return Info"| D["IdInfo with Age"]
A -->|"Address Code"| E["Address Database"]
E -->|"Supplement Data"| F["Enhanced Coverage"]
File Changes1. data/address_code.go
|
Code Review by Qodo
1. GetInfo skips validation
|
| func GetInfo(id string, strict bool) (IdInfo, error) { | ||
| // 验证有效性 | ||
| if !IsValid(id, strict) { | ||
| return IdInfo{}, errors.New("invalid ID card number") | ||
| code, err := generateCode(id) | ||
| if err != nil { | ||
| return IdInfo{}, err | ||
| } |
There was a problem hiding this comment.
1. Getinfo skips validation 🐞 Bug ≡ Correctness
GetInfo no longer validates order/birthday/address/checkbit and will return nil error for invalid IDs (including strict=true), producing incorrect Address/Birthday/Sex/Age results. This regresses existing behavior and breaks the current unit test expectation that strict GetInfo returns an error for IDs invalid in strict mode.
Agent Prompt
### Issue description
`GetInfo` currently returns parsed info even when the ID is invalid (including `strict=true`) because it no longer performs the same validation as `IsValid`.
### Issue Context
- `generateCode` only checks length and does permissive regex extraction; it does **not** validate birthday/address/checkbit.
- `IsValid` already encodes the library’s validation rules.
### Fix Focus Areas
- id_validator.go[62-67]
- id_validator.go[31-50]
### Suggested fix
Option A (simplest):
- Reintroduce `if !IsValid(id, strict) { return IdInfo{}, errors.New("invalid ID card number") }` at the top of `GetInfo`.
Option B (avoid double parsing):
- Keep the single `generateCode` call, but immediately apply the same checks as `IsValid` (order/birthday/address and for 18-digit IDs checkbit) and return the same error when validation fails.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
id_validator.go (1)
85-85:⚠️ Potential issue | 🟡 Minor生日解析错误被忽略。
time.ParseInLocation的错误被_忽略。若解析失败,birthday将为零值时间,calculateAge会返回约 2000+ 的异常年龄。考虑到上述验证逻辑移除问题,建议处理此错误:
- birthday, _ := time.ParseInLocation("20060102", code["birthdayCode"], cst) + birthday, err := time.ParseInLocation("20060102", code["birthdayCode"], cst) + if err != nil { + return IdInfo{}, errors.New("invalid birthday code") + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@id_validator.go` at line 85, The call to time.ParseInLocation ignores the error, so a failed parse leaves birthday as the zero time and calculateAge returns an absurd value; update the parsing in the function that calls time.ParseInLocation("20060102", code["birthdayCode"], cst) to capture the returned error, validate it, and handle it (e.g., return an explicit validation error or false result) instead of discarding it—ensure you reference the parsed variable birthday and the downstream calculateAge call when adding the error check so invalid birthdayCode values are rejected early.
🧹 Nitpick comments (1)
data/address_code.go (1)
3282-3324: 港澳台区县码这批新增数据当前不会被读取。
helper.goLine 17-29 对首位为8的地址码在解析完省级后就直接返回,checker.goLine 74-91 也只要求省级非空。所以810101-810118、820101-820103、830101-830120这批新增项不会进入GetInfo/校验链路;现在只是和AddressCodeTimeline并行维护的一份不可达数据。若目标是支持这些子区域,需要同步放开早返回逻辑;否则建议不要继续在这里扩充这类条目。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@data/address_code.go` around lines 3282 - 3324, The new HK/MO/TW sub-region codes (codes starting with '8') are never used because helper.go currently returns early after parsing province-level for codes whose first digit is '8' and checker.go only requires province-level non-empty; to fix, either stop adding these subregions or enable them by removing the early-return in the helper function that handles address parsing (the logic that bails out after province for leading '8') so GetInfo will continue parsing city/district levels, and update the validation in checker.go (the checker that only asserts province non-empty) to validate/allow deeper fields for codes starting with '8' so the AddressCodeTimeline entries become reachable. Ensure tests for GetInfo and the checker cover codes like 810101, 820101, and 830101.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@data/address_code.go`:
- Line 605: 这批以 xxxx01 结尾的历史码在 address_code.go 中被当成具体区名(例如
220101、420101、520101、620101 等),但 helper.go 注释(line 44-58)说明自 1984 年起 xxxx01
应为“市辖区”汇总码,具体区应使用 xxxx11 或其它历史编号;请审查 address_code.go 中所有匹配正则 /[0-9]{6}01/
的条目(包含评论提到的 220101、420101、520101、620101 及其同类行),根据 helper.go 的时间线把这些条目改回汇总名“市辖区”
或(若确认存在历史具体区码)把具体区名移动到对应的 xxxx11/正确历史码,并保持时间线回退逻辑一致;在更改时确保与 helper.go
的规则和注释一致,更新或删除重复/错位的具体区字符串以避免代码在有/无时间线时返回不一致地址。
In `@id_validator.go`:
- Around line 97-98: The age calculation uses time.Now() inside calculateAge
causing timezone drift; change calculateAge to accept a now time parameter
(e.g., calculateAge(birthday time.Time, now time.Time)) and update its
implementation in helper.go to compute age using the provided now, then update
the caller (where age := calculateAge(birthday)) to pass a now value that is in
Asia/Shanghai (use time.LoadLocation("Asia/Shanghai") and now.In(cst) when
creating the now argument) so both birthday and now are in the same timezone and
tests remain deterministic.
- Around line 64-67: GetInfo currently only calls generateCode (which only
checks length) so other important validations from IsValid are skipped; restore
the full validation flow by invoking IsValid (or performing the same checks)
inside GetInfo before calling generateCode and return an error when any check
fails; specifically ensure checkOrderCode, checkBirthdayCode, checkAddressCode
and generatorCheckBit are executed (or delegated to IsValid) and that GetInfo
returns an error instead of an IdInfo when any of those validations fail.
---
Outside diff comments:
In `@id_validator.go`:
- Line 85: The call to time.ParseInLocation ignores the error, so a failed parse
leaves birthday as the zero time and calculateAge returns an absurd value;
update the parsing in the function that calls time.ParseInLocation("20060102",
code["birthdayCode"], cst) to capture the returned error, validate it, and
handle it (e.g., return an explicit validation error or false result) instead of
discarding it—ensure you reference the parsed variable birthday and the
downstream calculateAge call when adding the error check so invalid birthdayCode
values are rejected early.
---
Nitpick comments:
In `@data/address_code.go`:
- Around line 3282-3324: The new HK/MO/TW sub-region codes (codes starting with
'8') are never used because helper.go currently returns early after parsing
province-level for codes whose first digit is '8' and checker.go only requires
province-level non-empty; to fix, either stop adding these subregions or enable
them by removing the early-return in the helper function that handles address
parsing (the logic that bails out after province for leading '8') so GetInfo
will continue parsing city/district levels, and update the validation in
checker.go (the checker that only asserts province non-empty) to validate/allow
deeper fields for codes starting with '8' so the AddressCodeTimeline entries
become reachable. Ensure tests for GetInfo and the checker cover codes like
810101, 820101, and 830101.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9b75b6d2-394e-4176-baa4-b7d503f4252e
📒 Files selected for processing (4)
data/address_code.godata/address_code_timeline.gohelper.goid_validator.go
🚧 Files skipped from review as they are similar to previous changes (1)
- helper.go
| 211481: "兴城市", | ||
| 220000: "吉林省", | ||
| 220100: "长春市", | ||
| 220101: "郊区", |
There was a problem hiding this comment.
这批 xxxx01 历史码看起来整体错位了。
helper.go Line 44-58 已明确说明:1984 年起地级市的 xxxx01 是“市辖区”汇总码,xxxx11 才开始给具体区/郊区编号。这里却把多处 ...101 录成了具体区名(例如 220101: "郊区"、420101: "汉桥区"、520101: "云岩区"、620101: "红古区")。这样时间线命中时会返回错误地址,而时间线缺失时又会回退成“市辖区”,同一代码会前后不一致。建议先整体复核同类 ...01 条目,确认是否应改为汇总码或 ...11/其他真实历史码。
Also applies to: 1177-1177, 1718-1718, 2526-2526, 2625-2625, 2772-2772, 2974-2974, 3076-3076
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@data/address_code.go` at line 605, 这批以 xxxx01 结尾的历史码在 address_code.go
中被当成具体区名(例如 220101、420101、520101、620101 等),但 helper.go 注释(line 44-58)说明自 1984 年起
xxxx01 应为“市辖区”汇总码,具体区应使用 xxxx11 或其它历史编号;请审查 address_code.go 中所有匹配正则 /[0-9]{6}01/
的条目(包含评论提到的 220101、420101、520101、620101 及其同类行),根据 helper.go 的时间线把这些条目改回汇总名“市辖区”
或(若确认存在历史具体区码)把具体区名移动到对应的 xxxx11/正确历史码,并保持时间线回退逻辑一致;在更改时确保与 helper.go
的规则和注释一致,更新或删除重复/错位的具体区字符串以避免代码在有/无时间线时返回不一致地址。
| code, err := generateCode(id) | ||
| if err != nil { | ||
| return IdInfo{}, err | ||
| } |
There was a problem hiding this comment.
验证逻辑不完整,可能接受无效身份证号。
移除 IsValid 预检查后,GetInfo 仅调用 generateCode,而 generateCode 只做长度校验。原本 IsValid 中的以下校验被跳过:
checkOrderCode(顺序码校验)checkBirthdayCode(出生日期校验)checkAddressCode(地址码校验)generatorCheckBit(18位校验码验证)
这将导致无效身份证号返回包含错误数据的 IdInfo,而非返回错误。
🐛 建议修复:保留完整验证逻辑
func GetInfo(id string, strict bool) (IdInfo, error) {
+ if !IsValid(id, strict) {
+ return IdInfo{}, errors.New("invalid ID card number")
+ }
code, err := generateCode(id)
if err != nil {
return IdInfo{}, err
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| code, err := generateCode(id) | |
| if err != nil { | |
| return IdInfo{}, err | |
| } | |
| func GetInfo(id string, strict bool) (IdInfo, error) { | |
| if !IsValid(id, strict) { | |
| return IdInfo{}, errors.New("invalid ID card number") | |
| } | |
| code, err := generateCode(id) | |
| if err != nil { | |
| return IdInfo{}, err | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@id_validator.go` around lines 64 - 67, GetInfo currently only calls
generateCode (which only checks length) so other important validations from
IsValid are skipped; restore the full validation flow by invoking IsValid (or
performing the same checks) inside GetInfo before calling generateCode and
return an error when any check fails; specifically ensure checkOrderCode,
checkBirthdayCode, checkAddressCode and generatorCheckBit are executed (or
delegated to IsValid) and that GetInfo returns an error instead of an IdInfo
when any of those validations fail.
| age := calculateAge(birthday) | ||
|
|
There was a problem hiding this comment.
时区不一致可能导致年龄计算错误。
birthday 使用 Asia/Shanghai 时区解析 (line 81-85),但 calculateAge 内部使用 time.Now() 获取的是系统本地时间。若服务器部署在其他时区,在跨日边界时刻可能导致年龄计算偏差一岁。
建议在 calculateAge 中也使用统一的时区,或将 now 转换为同一时区后再比较。
🔧 建议修复方案
方案一:在 helper.go 的 calculateAge 中统一使用 Asia/Shanghai 时区:
func calculateAge(birthday time.Time) int {
cst, _ := time.LoadLocation("Asia/Shanghai")
now := time.Now().In(cst)
// ...
}方案二:传递 now 参数使其可测试且时区一致:
func calculateAge(birthday time.Time, now time.Time) int {
age := now.Year() - birthday.Year()
// ...
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@id_validator.go` around lines 97 - 98, The age calculation uses time.Now()
inside calculateAge causing timezone drift; change calculateAge to accept a now
time parameter (e.g., calculateAge(birthday time.Time, now time.Time)) and
update its implementation in helper.go to compute age using the provided now,
then update the caller (where age := calculateAge(birthday)) to pass a now value
that is in Asia/Shanghai (use time.LoadLocation("Asia/Shanghai") and now.In(cst)
when creating the now argument) so both birthday and now are in the same
timezone and tests remain deterministic.
|
@mengxw777 抱歉刚看到,不过看起来测试没有通过 |
PR Type
Enhancement
Description
Add age calculation functionality to GetInfo method
Import time package for birthday-based age computation
Add Age field to IdInfo struct for age information
Implement getAge helper function with YearDay logic
Diagram Walkthrough
File Walkthrough
helper.go
Add getAge helper function for age calculationhelper.go
YearDay comparison
id_validator.go
Add Age field and calculation to IdInfoid_validator.go
Summary by CodeRabbit
发布说明
✏️ Tip: You can customize this high-level summary in your review settings.