Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions pkg/base/context/login_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,12 @@ func ExtractIDFromLoginData(data *model.LoginData) string {
}

// ExtractIDFromIdentifier 从 Identifier 中提取学号
// 本科生:从id截取 9 位 如: 20241025133150102401339
// 研究生:id直接是stuId可能是 9 或 10 位
// 研究生:id直接是stuId,以 00000 为前缀(可能是 9 或 10 位)
// 本科生:identifier 末尾为学号,按入学年份判断是 9 位还是 10 位
// 2026年开始本科生学号由9位变到10位
// 本科生identifier规则:yyyymmdd + hhmmss + 学号,长度不定
// 比如2026年8月5日,开头就是202685,12月17日就是20261217
// 时间也是一样,24小时制,当日1时50分07秒就是1507,10时0分0秒就是1000,12时37分59秒就是123759
func ExtractIDFromIdentifier(id string) string {
if len(id) < constants.StudentIDLength {
return ""
Expand All @@ -75,5 +79,5 @@ func ExtractIDFromIdentifier(id string) string {
}

// 本科生
return id[len(id)-constants.StudentIDLength:]
return utils.RemoveUndergraduatePrefix(id)
}
68 changes: 68 additions & 0 deletions pkg/base/context/login_data_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
Copyright 2024 The west2-online Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package context

import "testing"

func TestExtractIDFromIdentifier(t *testing.T) {
tests := []struct {
name string
id string
want string
}{
{
name: "研究生-9位学号",
// 00000 + 102301001
id: "00000102301001",
want: "102301001",
},
{
name: "研究生-10位学号",
// 00000 + 1026012345
id: "000001026012345",
want: "1026012345",
},
{
name: "本科生-9位学号",
id: "20268514814222200311",
want: "222200311",
},
{
name: "本科生-10位学号",
id: "202685148141026012345",
want: "1026012345",
Comment thread
ACaiCat marked this conversation as resolved.
Outdated
},
{
name: "过短",
id: "123",
want: "",
},
{
name: "空",
id: "",
want: "",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ExtractIDFromIdentifier(tt.id); got != tt.want {
t.Errorf("ExtractIDFromIdentifier() = %v, want %v", got, tt.want)
}
})
}
}
7 changes: 6 additions & 1 deletion pkg/constants/jwch.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ package constants

const (
MaxRetries = 5 // 最大重试次数
StudentIDLength = 9 // 学号的长度,用于截取处学号
StudentIDLength = 9 // 本科基础学号长度(2026年前入学为9位),也是从 identifier 提取时的最小长度
InitialDelay = 1 * ONE_SECOND // 初始等待时间
YjsTermLen = 6 // 研究生学期长度
JwchTermLen = 6

// 2026年(含)起入学的新生学号由9位变为10位。
// 学号第3-4位为入学年份(如 22/25/26),年份 >= StudentIDYearThreshold 时为10位新学号。
StudentIDLengthNew = 10
StudentIDYearThreshold = "26"
Comment thread
ACaiCat marked this conversation as resolved.
Outdated
)
17 changes: 15 additions & 2 deletions pkg/utils/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package utils

import (
"strings"

"github.com/west2-online/fzuhelper-server/pkg/constants"
)

// IsGraduate 根据 identifier 判断是否是研究生
Expand All @@ -35,7 +37,18 @@ func MarkGraduate(id string) string {
return "00000" + id
}

// RemoveUndergraduatePrefix 去除本科生的学号前缀
// RemoveUndergraduatePrefix 去除本科生的学号前缀,返回真实学号。
// 学号格式为 xxyyxxxxx(9位,2026年前入学)或 xxyyxxxxxx(10位,2026年起入学),
Comment thread
Penty-d marked this conversation as resolved.
Outdated
// 其中第3-4位 yy 为入学年份,通过年份判断学号位数。
func RemoveUndergraduatePrefix(id string) string {
return id[len(id)-9:]
if len(id) < constants.StudentIDLength {
return ""
}
// 先取后9位,其第3-4位为入学年份
last9 := id[len(id)-constants.StudentIDLength:]
// 年份 >= 26(2026年起入学)为10位新学号,取后10位
if len(id) >= constants.StudentIDLengthNew && last9[2:4] >= constants.StudentIDYearThreshold {
Comment thread
ACaiCat marked this conversation as resolved.
Outdated
return id[len(id)-constants.StudentIDLengthNew:]
}
return last9
}
69 changes: 69 additions & 0 deletions pkg/utils/id_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
Copyright 2024 The west2-online Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package utils

import "testing"

func TestRemoveUndergraduatePrefix(t *testing.T) {
tests := []struct {
name string
id string
want string
}{
{
name: "9位学号-2022年入学",
// 后9位 222200311,第3-4位 22 < 26
id: "20268514814222200311",
want: "222200311",
},
{
name: "9位学号-2025年入学",
// 后9位 102512345,第3-4位 25 < 26
id: "20268514814102512345",
want: "102512345",
},
{
name: "10位学号-2026年入学",
// 后9位 026012345,第3-4位 60 >= 26,取后10位
id: "202685148141026012345",
want: "1026012345",
},
{
name: "identifier即学号-9位",
id: "222200311",
want: "222200311",
},
{
name: "过短",
id: "12345678",
want: "",
},
{
name: "空",
id: "",
want: "",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := RemoveUndergraduatePrefix(tt.id); got != tt.want {
t.Errorf("RemoveUndergraduatePrefix() = %v, want %v", got, tt.want)
}
})
}
}