删除了ai识别验证码部分,新增个人成绩补考标识和cet成绩查询
This commit is contained in:
@@ -1,55 +1,7 @@
|
|||||||
package captcha
|
package captcha
|
||||||
|
|
||||||
import (
|
// GetCaptchaCode 返回固定验证码
|
||||||
"fmt"
|
// 教务系统验证码已不再需要识别,直接使用固定值
|
||||||
"io"
|
func GetCaptchaCode() string {
|
||||||
"log/slog"
|
return "...."
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"schedule_converter/client"
|
|
||||||
"schedule_converter/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
func SaveCaptchaImage(httpClient *http.Client) ([]byte, error) {
|
|
||||||
req, err := http.NewRequest("GET", config.Get().BaseURL+"/captchaImage", nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req.Header = client.GetHeaders()
|
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return nil, fmt.Errorf("获取验证码失败, 状态码: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return body, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetAndRecognize(httpClient *http.Client) (string, error) {
|
|
||||||
_, err := SaveCaptchaImage(httpClient)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
captchaCode, err := Recognize("captcha.png")
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
slog.Debug("验证码识别完成", "result", captchaCode)
|
|
||||||
return captchaCode, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Recognize(imagePath string) (string, error) {
|
|
||||||
return "....", nil
|
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log/slog"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@@ -14,14 +12,6 @@ type Config struct {
|
|||||||
Password string
|
Password string
|
||||||
Semester string
|
Semester string
|
||||||
TWFID string
|
TWFID string
|
||||||
Recognizer RecognizerConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
type RecognizerConfig struct {
|
|
||||||
APIURL string
|
|
||||||
APIKey string
|
|
||||||
Model string
|
|
||||||
Timeout time.Duration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -37,16 +27,6 @@ func Load() *Config {
|
|||||||
Password: getEnv("JWTS_PASSWORD", "wyb12580963"),
|
Password: getEnv("JWTS_PASSWORD", "wyb12580963"),
|
||||||
Semester: getEnv("JWTS_SEMESTER", "2025-20262"),
|
Semester: getEnv("JWTS_SEMESTER", "2025-20262"),
|
||||||
TWFID: getEnv("JWTS_TWFID", ""),
|
TWFID: getEnv("JWTS_TWFID", ""),
|
||||||
Recognizer: RecognizerConfig{
|
|
||||||
APIURL: getEnv("RECOGNIZER_API_URL", "https://api.littlelan.cn/v1/chat/completions"),
|
|
||||||
APIKey: getEnv("RECOGNIZER_API_KEY", "sk-6064466699a996b6f83e1ae8247c1cb4eeb4b72ce23cb001204335a2567d63c1"),
|
|
||||||
Model: getEnv("RECOGNIZER_MODEL", "qwen3.5-plus"),
|
|
||||||
Timeout: getEnvDuration("RECOGNIZER_TIMEOUT", 120*time.Second),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.Recognizer.APIKey == "" {
|
|
||||||
slog.Warn("RECOGNIZER_API_KEY not set, image recognition will not work")
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return cfg
|
return cfg
|
||||||
@@ -78,24 +58,10 @@ func getEnvInt(key string, defaultValue int) int {
|
|||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEnvDuration(key string, defaultValue time.Duration) time.Duration {
|
|
||||||
val := os.Getenv(key)
|
|
||||||
if val == "" {
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
if d, err := time.ParseDuration(val); err == nil {
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
BaseURL = Get().BaseURL
|
BaseURL = Get().BaseURL
|
||||||
Username = Get().Username
|
Username = Get().Username
|
||||||
Password = Get().Password
|
Password = Get().Password
|
||||||
Semester = Get().Semester
|
Semester = Get().Semester
|
||||||
TWFID = Get().TWFID
|
TWFID = Get().TWFID
|
||||||
RecognizerAPIURL = Get().Recognizer.APIURL
|
|
||||||
RecognizerAPIKey = Get().Recognizer.APIKey
|
|
||||||
RecognizerModel = Get().Recognizer.Model
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ func convertGrades(grades []parser.GradeEntry) []*pb.Grade {
|
|||||||
Score: g.Score,
|
Score: g.Score,
|
||||||
GradePoint: g.GradePoint,
|
GradePoint: g.GradePoint,
|
||||||
IsExam: g.IsExam,
|
IsExam: g.IsExam,
|
||||||
|
IsRetake: g.IsRetake,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@@ -89,3 +90,29 @@ func convertEmptyClassrooms(entries []parser.EmptyClassroomEntry) []*pb.EmptyCla
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func convertCETStudentInfo(info parser.CETStudentInfo) *pb.CetStudentInfo {
|
||||||
|
return &pb.CetStudentInfo{
|
||||||
|
StudentId: info.StudentID,
|
||||||
|
Name: info.Name,
|
||||||
|
Gender: info.Gender,
|
||||||
|
IdCard: info.IDCard,
|
||||||
|
Duration: info.Duration,
|
||||||
|
Grade: info.Grade,
|
||||||
|
College: info.College,
|
||||||
|
Major: info.Major,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertCETScores(scores []parser.CETScore) []*pb.CetScore {
|
||||||
|
result := make([]*pb.CetScore, 0, len(scores))
|
||||||
|
for _, s := range scores {
|
||||||
|
result = append(result, &pb.CetScore{
|
||||||
|
Level: s.Level,
|
||||||
|
ExamTime: s.ExamTime,
|
||||||
|
TicketNum: s.TicketNum,
|
||||||
|
Score: s.Score,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ func (h *TaskHandler) dispatch(ctx context.Context, task *pb.Task) ([]byte, erro
|
|||||||
return h.login(ctx, task.Payload)
|
return h.login(ctx, task.Payload)
|
||||||
case pb.TaskType_TASK_TYPE_GET_EMPTY_CLASSROOM:
|
case pb.TaskType_TASK_TYPE_GET_EMPTY_CLASSROOM:
|
||||||
return h.getEmptyClassrooms(ctx, task.Payload)
|
return h.getEmptyClassrooms(ctx, task.Payload)
|
||||||
|
case pb.TaskType_TASK_TYPE_GET_CET:
|
||||||
|
return h.getCET(ctx, task.Payload)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("%w: %v", errUnknownTaskType, task.Type)
|
return nil, fmt.Errorf("%w: %v", errUnknownTaskType, task.Type)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const (
|
|||||||
func createHTTPClient() (*http.Client, error) {
|
func createHTTPClient() (*http.Client, error) {
|
||||||
jar, err := cookiejar.New(nil)
|
jar, err := cookiejar.New(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, apperr.New("create_jar", err, "创建 cookie jar 失败")
|
return nil, apperr.New("create_jar", err, "鍒涘缓 cookie jar 澶辫触")
|
||||||
}
|
}
|
||||||
return &http.Client{Jar: jar}, nil
|
return &http.Client{Jar: jar}, nil
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ func setTWFIDCookie(httpClient *http.Client, baseURL, twfid string) {
|
|||||||
}
|
}
|
||||||
u, err := url.Parse(baseURL)
|
u, err := url.Parse(baseURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Warn("解析 baseURL 失败,无法设置 TWFID cookie", "base_url", baseURL, "error", err)
|
slog.Warn("瑙f瀽 baseURL 澶辫触锛屾棤娉曡缃?TWFID cookie", "base_url", baseURL, "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
httpClient.Jar.SetCookies(u, []*http.Cookie{
|
httpClient.Jar.SetCookies(u, []*http.Cookie{
|
||||||
@@ -50,7 +50,7 @@ func executeLogin(ctx context.Context, httpClient *http.Client, username, passwo
|
|||||||
log := slog.With("username", username)
|
log := slog.With("username", username)
|
||||||
|
|
||||||
if err := client.GetInitialCookiesWithClient(httpClient); err != nil {
|
if err := client.GetInitialCookiesWithClient(httpClient); err != nil {
|
||||||
return apperr.New("get_cookies", err, "获取初始 Cookie 失败")
|
return apperr.New("get_cookies", err, "鑾峰彇鍒濆 Cookie 澶辫触")
|
||||||
}
|
}
|
||||||
|
|
||||||
for attempt := 1; attempt <= maxLoginRetries; attempt++ {
|
for attempt := 1; attempt <= maxLoginRetries; attempt++ {
|
||||||
@@ -60,18 +60,12 @@ func executeLogin(ctx context.Context, httpClient *http.Client, username, passwo
|
|||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("尝试登录", "attempt", attempt, "max_retries", maxLoginRetries)
|
log.Info("灏濊瘯鐧诲綍", "attempt", attempt, "max_retries", maxLoginRetries)
|
||||||
|
|
||||||
captchaCode, err := captcha.GetAndRecognize(httpClient)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("验证码获取失败", "error", err, "attempt", attempt)
|
|
||||||
time.Sleep(loginRetryInterval)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
|
captchaCode := captcha.GetCaptchaCode()
|
||||||
success, err := auth.LoginWithClient(httpClient, captchaCode, username, password)
|
success, err := auth.LoginWithClient(httpClient, captchaCode, username, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("登录请求失败", "error", err, "attempt", attempt)
|
log.Warn("鐧诲綍璇锋眰澶辫触", "error", err, "attempt", attempt)
|
||||||
time.Sleep(loginRetryInterval)
|
time.Sleep(loginRetryInterval)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -80,7 +74,7 @@ func executeLogin(ctx context.Context, httpClient *http.Client, username, passwo
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Warn("登录验证失败", "attempt", attempt)
|
log.Warn("鐧诲綍楠岃瘉澶辫触", "attempt", attempt)
|
||||||
time.Sleep(loginRetryInterval)
|
time.Sleep(loginRetryInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +96,7 @@ func executeLoginAndFetchSchedule(ctx context.Context, httpClient *http.Client,
|
|||||||
|
|
||||||
func unmarshalPayload(payload []byte, v any) error {
|
func unmarshalPayload(payload []byte, v any) error {
|
||||||
if err := json.Unmarshal(payload, v); err != nil {
|
if err := json.Unmarshal(payload, v); err != nil {
|
||||||
return apperr.New("parse_payload", err, "解析任务载荷失败")
|
return apperr.New("parse_payload", err, "瑙f瀽浠诲姟杞借嵎澶辫触")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ type GradeEntry struct {
|
|||||||
Score string
|
Score string
|
||||||
GradePoint string
|
GradePoint string
|
||||||
IsExam string
|
IsExam string
|
||||||
|
IsRetake bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type GPASummary struct {
|
type GPASummary struct {
|
||||||
@@ -139,7 +140,7 @@ func parseGradesHTML(html string) ([]GradeEntry, error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
texts := getCellTexts(cells)
|
texts, isRetake := getCellTextsAndRetake(cells)
|
||||||
if len(texts) < 9 {
|
if len(texts) < 9 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -151,6 +152,7 @@ func parseGradesHTML(html string) ([]GradeEntry, error) {
|
|||||||
Code: safeGet(texts, 3),
|
Code: safeGet(texts, 3),
|
||||||
Name: safeGet(texts, 4),
|
Name: safeGet(texts, 4),
|
||||||
Credit: safeGet(texts, 7),
|
Credit: safeGet(texts, 7),
|
||||||
|
IsRetake: isRetake,
|
||||||
}
|
}
|
||||||
|
|
||||||
if isMidterm {
|
if isMidterm {
|
||||||
@@ -227,7 +229,7 @@ func parseGPAHTML(html string) (*GPASummary, []GradeEntry, error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
texts := getCellTexts(cells)
|
texts, isRetake := getCellTextsAndRetake(cells)
|
||||||
|
|
||||||
entry := GradeEntry{
|
entry := GradeEntry{
|
||||||
Term: safeGet(texts, 0),
|
Term: safeGet(texts, 0),
|
||||||
@@ -239,6 +241,7 @@ func parseGPAHTML(html string) (*GPASummary, []GradeEntry, error) {
|
|||||||
Credit: safeGet(texts, 7),
|
Credit: safeGet(texts, 7),
|
||||||
Score: safeGet(texts, 8),
|
Score: safeGet(texts, 8),
|
||||||
GradePoint: safeGet(texts, 9),
|
GradePoint: safeGet(texts, 9),
|
||||||
|
IsRetake: isRetake,
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.Name != "" && len(entry.Name) >= 2 {
|
if entry.Name != "" && len(entry.Name) >= 2 {
|
||||||
@@ -250,6 +253,32 @@ func parseGPAHTML(html string) (*GPASummary, []GradeEntry, error) {
|
|||||||
return summary, grades, nil
|
return summary, grades, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getCellTextsAndRetake 解析单元格文本,同时检测是否包含补考标记
|
||||||
|
// 补考标记在HTML中表现为 <font color="#0066ff">补考</font>,
|
||||||
|
// 解析后该单元格文本为"补考",需要从texts中移除并记录isRetake标志
|
||||||
|
func getCellTextsAndRetake(cells *goquery.Selection) ([]string, bool) {
|
||||||
|
var texts []string
|
||||||
|
isRetake := false
|
||||||
|
retakeIndex := -1
|
||||||
|
|
||||||
|
cells.Each(func(i int, cell *goquery.Selection) {
|
||||||
|
text := strings.TrimSpace(cell.Text())
|
||||||
|
// 检测补考标记:<font color="#0066ff">补考</font>
|
||||||
|
if text == "补考" {
|
||||||
|
isRetake = true
|
||||||
|
retakeIndex = i
|
||||||
|
}
|
||||||
|
texts = append(texts, text)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 移除"补考"这一列,使后续列索引与正常行一致
|
||||||
|
if isRetake && retakeIndex >= 0 {
|
||||||
|
texts = append(texts[:retakeIndex], texts[retakeIndex+1:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return texts, isRetake
|
||||||
|
}
|
||||||
|
|
||||||
func getCellTexts(cells *goquery.Selection) []string {
|
func getCellTexts(cells *goquery.Selection) []string {
|
||||||
var texts []string
|
var texts []string
|
||||||
cells.Each(func(_ int, cell *goquery.Selection) {
|
cells.Each(func(_ int, cell *goquery.Selection) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v7.34.1
|
// protoc v6.32.0
|
||||||
// source: proto/runner/runner.proto
|
// source: proto/runner/runner.proto
|
||||||
|
|
||||||
package runner
|
package runner
|
||||||
@@ -32,6 +32,7 @@ const (
|
|||||||
TaskType_TASK_TYPE_GET_EXAMS TaskType = 4 // 获取考试安排
|
TaskType_TASK_TYPE_GET_EXAMS TaskType = 4 // 获取考试安排
|
||||||
TaskType_TASK_TYPE_GET_USER_INFO TaskType = 5 // 获取用户信息
|
TaskType_TASK_TYPE_GET_USER_INFO TaskType = 5 // 获取用户信息
|
||||||
TaskType_TASK_TYPE_GET_EMPTY_CLASSROOM TaskType = 6 // 获取空教室
|
TaskType_TASK_TYPE_GET_EMPTY_CLASSROOM TaskType = 6 // 获取空教室
|
||||||
|
TaskType_TASK_TYPE_GET_CET TaskType = 7 // 获取四六级成绩
|
||||||
)
|
)
|
||||||
|
|
||||||
// Enum value maps for TaskType.
|
// Enum value maps for TaskType.
|
||||||
@@ -44,6 +45,7 @@ var (
|
|||||||
4: "TASK_TYPE_GET_EXAMS",
|
4: "TASK_TYPE_GET_EXAMS",
|
||||||
5: "TASK_TYPE_GET_USER_INFO",
|
5: "TASK_TYPE_GET_USER_INFO",
|
||||||
6: "TASK_TYPE_GET_EMPTY_CLASSROOM",
|
6: "TASK_TYPE_GET_EMPTY_CLASSROOM",
|
||||||
|
7: "TASK_TYPE_GET_CET",
|
||||||
}
|
}
|
||||||
TaskType_value = map[string]int32{
|
TaskType_value = map[string]int32{
|
||||||
"TASK_TYPE_UNKNOWN": 0,
|
"TASK_TYPE_UNKNOWN": 0,
|
||||||
@@ -53,6 +55,7 @@ var (
|
|||||||
"TASK_TYPE_GET_EXAMS": 4,
|
"TASK_TYPE_GET_EXAMS": 4,
|
||||||
"TASK_TYPE_GET_USER_INFO": 5,
|
"TASK_TYPE_GET_USER_INFO": 5,
|
||||||
"TASK_TYPE_GET_EMPTY_CLASSROOM": 6,
|
"TASK_TYPE_GET_EMPTY_CLASSROOM": 6,
|
||||||
|
"TASK_TYPE_GET_CET": 7,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1378,6 +1381,7 @@ type Grade struct {
|
|||||||
Score string `protobuf:"bytes,7,opt,name=score,proto3" json:"score,omitempty"` // 成绩 (可能是等级或分数)
|
Score string `protobuf:"bytes,7,opt,name=score,proto3" json:"score,omitempty"` // 成绩 (可能是等级或分数)
|
||||||
GradePoint string `protobuf:"bytes,8,opt,name=grade_point,json=gradePoint,proto3" json:"grade_point,omitempty"` // 绩点
|
GradePoint string `protobuf:"bytes,8,opt,name=grade_point,json=gradePoint,proto3" json:"grade_point,omitempty"` // 绩点
|
||||||
IsExam string `protobuf:"bytes,9,opt,name=is_exam,json=isExam,proto3" json:"is_exam,omitempty"` // 是否考试课
|
IsExam string `protobuf:"bytes,9,opt,name=is_exam,json=isExam,proto3" json:"is_exam,omitempty"` // 是否考试课
|
||||||
|
IsRetake bool `protobuf:"varint,10,opt,name=is_retake,json=isRetake,proto3" json:"is_retake,omitempty"` // 是否为补考
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
@@ -1475,6 +1479,13 @@ func (x *Grade) GetIsExam() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *Grade) GetIsRetake() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.IsRetake
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// ExamsResultData 考试安排结果数据
|
// ExamsResultData 考试安排结果数据
|
||||||
type ExamsResultData struct {
|
type ExamsResultData struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
@@ -1945,6 +1956,282 @@ func (x *EmptyClassroomEntry) GetWeeks() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCetPayload 获取四六级成绩任务载荷
|
||||||
|
type GetCetPayload struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` // 学号
|
||||||
|
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` // 密码
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetCetPayload) Reset() {
|
||||||
|
*x = GetCetPayload{}
|
||||||
|
mi := &file_proto_runner_runner_proto_msgTypes[24]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetCetPayload) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*GetCetPayload) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *GetCetPayload) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_proto_runner_runner_proto_msgTypes[24]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use GetCetPayload.ProtoReflect.Descriptor instead.
|
||||||
|
func (*GetCetPayload) Descriptor() ([]byte, []int) {
|
||||||
|
return file_proto_runner_runner_proto_rawDescGZIP(), []int{24}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetCetPayload) GetUsername() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Username
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetCetPayload) GetPassword() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Password
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// CetScore 四六级成绩条目
|
||||||
|
type CetScore struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
Level string `protobuf:"bytes,1,opt,name=level,proto3" json:"level,omitempty"` // 等级(英语四级/英语六级)
|
||||||
|
ExamTime string `protobuf:"bytes,2,opt,name=exam_time,json=examTime,proto3" json:"exam_time,omitempty"` // 考试时间,如 2025年06月
|
||||||
|
TicketNum string `protobuf:"bytes,3,opt,name=ticket_num,json=ticketNum,proto3" json:"ticket_num,omitempty"` // 准考证号
|
||||||
|
Score string `protobuf:"bytes,4,opt,name=score,proto3" json:"score,omitempty"` // 成绩
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetScore) Reset() {
|
||||||
|
*x = CetScore{}
|
||||||
|
mi := &file_proto_runner_runner_proto_msgTypes[25]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetScore) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CetScore) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *CetScore) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_proto_runner_runner_proto_msgTypes[25]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use CetScore.ProtoReflect.Descriptor instead.
|
||||||
|
func (*CetScore) Descriptor() ([]byte, []int) {
|
||||||
|
return file_proto_runner_runner_proto_rawDescGZIP(), []int{25}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetScore) GetLevel() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Level
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetScore) GetExamTime() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.ExamTime
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetScore) GetTicketNum() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.TicketNum
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetScore) GetScore() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Score
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// CetStudentInfo 四六级查询页面的学生信息
|
||||||
|
type CetStudentInfo struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
StudentId string `protobuf:"bytes,1,opt,name=student_id,json=studentId,proto3" json:"student_id,omitempty"` // 学号
|
||||||
|
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // 姓名
|
||||||
|
Gender string `protobuf:"bytes,3,opt,name=gender,proto3" json:"gender,omitempty"` // 性别
|
||||||
|
IdCard string `protobuf:"bytes,4,opt,name=id_card,json=idCard,proto3" json:"id_card,omitempty"` // 身份证号
|
||||||
|
Duration string `protobuf:"bytes,5,opt,name=duration,proto3" json:"duration,omitempty"` // 学制
|
||||||
|
Grade string `protobuf:"bytes,6,opt,name=grade,proto3" json:"grade,omitempty"` // 年级
|
||||||
|
College string `protobuf:"bytes,7,opt,name=college,proto3" json:"college,omitempty"` // 学院
|
||||||
|
Major string `protobuf:"bytes,8,opt,name=major,proto3" json:"major,omitempty"` // 专业
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetStudentInfo) Reset() {
|
||||||
|
*x = CetStudentInfo{}
|
||||||
|
mi := &file_proto_runner_runner_proto_msgTypes[26]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetStudentInfo) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CetStudentInfo) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *CetStudentInfo) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_proto_runner_runner_proto_msgTypes[26]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use CetStudentInfo.ProtoReflect.Descriptor instead.
|
||||||
|
func (*CetStudentInfo) Descriptor() ([]byte, []int) {
|
||||||
|
return file_proto_runner_runner_proto_rawDescGZIP(), []int{26}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetStudentInfo) GetStudentId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.StudentId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetStudentInfo) GetName() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Name
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetStudentInfo) GetGender() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Gender
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetStudentInfo) GetIdCard() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.IdCard
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetStudentInfo) GetDuration() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Duration
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetStudentInfo) GetGrade() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Grade
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetStudentInfo) GetCollege() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.College
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetStudentInfo) GetMajor() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Major
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// CetResultData 四六级成绩结果数据
|
||||||
|
type CetResultData struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
StudentInfo *CetStudentInfo `protobuf:"bytes,1,opt,name=student_info,json=studentInfo,proto3" json:"student_info,omitempty"` // 学生信息
|
||||||
|
Scores []*CetScore `protobuf:"bytes,2,rep,name=scores,proto3" json:"scores,omitempty"` // 成绩列表
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetResultData) Reset() {
|
||||||
|
*x = CetResultData{}
|
||||||
|
mi := &file_proto_runner_runner_proto_msgTypes[27]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetResultData) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CetResultData) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *CetResultData) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_proto_runner_runner_proto_msgTypes[27]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use CetResultData.ProtoReflect.Descriptor instead.
|
||||||
|
func (*CetResultData) Descriptor() ([]byte, []int) {
|
||||||
|
return file_proto_runner_runner_proto_rawDescGZIP(), []int{27}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetResultData) GetStudentInfo() *CetStudentInfo {
|
||||||
|
if x != nil {
|
||||||
|
return x.StudentInfo
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CetResultData) GetScores() []*CetScore {
|
||||||
|
if x != nil {
|
||||||
|
return x.Scores
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var File_proto_runner_runner_proto protoreflect.FileDescriptor
|
var File_proto_runner_runner_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
const file_proto_runner_runner_proto_rawDesc = "" +
|
const file_proto_runner_runner_proto_rawDesc = "" +
|
||||||
@@ -2047,7 +2334,7 @@ const file_proto_runner_runner_proto_rawDesc = "" +
|
|||||||
"student_id\x18\x02 \x01(\tR\tstudentId\x12%\n" +
|
"student_id\x18\x02 \x01(\tR\tstudentId\x12%\n" +
|
||||||
"\x06grades\x18\x03 \x03(\v2\r.runner.GradeR\x06grades\x123\n" +
|
"\x06grades\x18\x03 \x03(\v2\r.runner.GradeR\x06grades\x123\n" +
|
||||||
"\vgpa_summary\x18\x04 \x01(\v2\x12.runner.GpaSummaryR\n" +
|
"\vgpa_summary\x18\x04 \x01(\v2\x12.runner.GpaSummaryR\n" +
|
||||||
"gpaSummary\"\xf9\x01\n" +
|
"gpaSummary\"\x96\x02\n" +
|
||||||
"\x05Grade\x12\x12\n" +
|
"\x05Grade\x12\x12\n" +
|
||||||
"\x04term\x18\x01 \x01(\tR\x04term\x12\x1f\n" +
|
"\x04term\x18\x01 \x01(\tR\x04term\x12\x1f\n" +
|
||||||
"\vcourse_code\x18\x02 \x01(\tR\n" +
|
"\vcourse_code\x18\x02 \x01(\tR\n" +
|
||||||
@@ -2060,7 +2347,9 @@ const file_proto_runner_runner_proto_rawDesc = "" +
|
|||||||
"\x05score\x18\a \x01(\tR\x05score\x12\x1f\n" +
|
"\x05score\x18\a \x01(\tR\x05score\x12\x1f\n" +
|
||||||
"\vgrade_point\x18\b \x01(\tR\n" +
|
"\vgrade_point\x18\b \x01(\tR\n" +
|
||||||
"gradePoint\x12\x17\n" +
|
"gradePoint\x12\x17\n" +
|
||||||
"\ais_exam\x18\t \x01(\tR\x06isExam\"p\n" +
|
"\ais_exam\x18\t \x01(\tR\x06isExam\x12\x1b\n" +
|
||||||
|
"\tis_retake\x18\n" +
|
||||||
|
" \x01(\bR\bisRetake\"p\n" +
|
||||||
"\x0fExamsResultData\x12\x1a\n" +
|
"\x0fExamsResultData\x12\x1a\n" +
|
||||||
"\bsemester\x18\x01 \x01(\tR\bsemester\x12\x1d\n" +
|
"\bsemester\x18\x01 \x01(\tR\bsemester\x12\x1d\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
@@ -2106,7 +2395,29 @@ const file_proto_runner_runner_proto_rawDesc = "" +
|
|||||||
"\aweekday\x18\x02 \x01(\tR\aweekday\x12\x18\n" +
|
"\aweekday\x18\x02 \x01(\tR\aweekday\x12\x18\n" +
|
||||||
"\aperiods\x18\x03 \x01(\tR\aperiods\x12\x12\n" +
|
"\aperiods\x18\x03 \x01(\tR\aperiods\x12\x12\n" +
|
||||||
"\x04term\x18\x04 \x01(\tR\x04term\x12\x14\n" +
|
"\x04term\x18\x04 \x01(\tR\x04term\x12\x14\n" +
|
||||||
"\x05weeks\x18\x05 \x01(\tR\x05weeks*\xc5\x01\n" +
|
"\x05weeks\x18\x05 \x01(\tR\x05weeks\"G\n" +
|
||||||
|
"\rGetCetPayload\x12\x1a\n" +
|
||||||
|
"\busername\x18\x01 \x01(\tR\busername\x12\x1a\n" +
|
||||||
|
"\bpassword\x18\x02 \x01(\tR\bpassword\"r\n" +
|
||||||
|
"\bCetScore\x12\x14\n" +
|
||||||
|
"\x05level\x18\x01 \x01(\tR\x05level\x12\x1b\n" +
|
||||||
|
"\texam_time\x18\x02 \x01(\tR\bexamTime\x12\x1d\n" +
|
||||||
|
"\n" +
|
||||||
|
"ticket_num\x18\x03 \x01(\tR\tticketNum\x12\x14\n" +
|
||||||
|
"\x05score\x18\x04 \x01(\tR\x05score\"\xd6\x01\n" +
|
||||||
|
"\x0eCetStudentInfo\x12\x1d\n" +
|
||||||
|
"\n" +
|
||||||
|
"student_id\x18\x01 \x01(\tR\tstudentId\x12\x12\n" +
|
||||||
|
"\x04name\x18\x02 \x01(\tR\x04name\x12\x16\n" +
|
||||||
|
"\x06gender\x18\x03 \x01(\tR\x06gender\x12\x17\n" +
|
||||||
|
"\aid_card\x18\x04 \x01(\tR\x06idCard\x12\x1a\n" +
|
||||||
|
"\bduration\x18\x05 \x01(\tR\bduration\x12\x14\n" +
|
||||||
|
"\x05grade\x18\x06 \x01(\tR\x05grade\x12\x18\n" +
|
||||||
|
"\acollege\x18\a \x01(\tR\acollege\x12\x14\n" +
|
||||||
|
"\x05major\x18\b \x01(\tR\x05major\"t\n" +
|
||||||
|
"\rCetResultData\x129\n" +
|
||||||
|
"\fstudent_info\x18\x01 \x01(\v2\x16.runner.CetStudentInfoR\vstudentInfo\x12(\n" +
|
||||||
|
"\x06scores\x18\x02 \x03(\v2\x10.runner.CetScoreR\x06scores*\xdc\x01\n" +
|
||||||
"\bTaskType\x12\x15\n" +
|
"\bTaskType\x12\x15\n" +
|
||||||
"\x11TASK_TYPE_UNKNOWN\x10\x00\x12\x13\n" +
|
"\x11TASK_TYPE_UNKNOWN\x10\x00\x12\x13\n" +
|
||||||
"\x0fTASK_TYPE_LOGIN\x10\x01\x12\x1a\n" +
|
"\x0fTASK_TYPE_LOGIN\x10\x01\x12\x1a\n" +
|
||||||
@@ -2114,7 +2425,8 @@ const file_proto_runner_runner_proto_rawDesc = "" +
|
|||||||
"\x14TASK_TYPE_GET_GRADES\x10\x03\x12\x17\n" +
|
"\x14TASK_TYPE_GET_GRADES\x10\x03\x12\x17\n" +
|
||||||
"\x13TASK_TYPE_GET_EXAMS\x10\x04\x12\x1b\n" +
|
"\x13TASK_TYPE_GET_EXAMS\x10\x04\x12\x1b\n" +
|
||||||
"\x17TASK_TYPE_GET_USER_INFO\x10\x05\x12!\n" +
|
"\x17TASK_TYPE_GET_USER_INFO\x10\x05\x12!\n" +
|
||||||
"\x1dTASK_TYPE_GET_EMPTY_CLASSROOM\x10\x06*\x8a\x01\n" +
|
"\x1dTASK_TYPE_GET_EMPTY_CLASSROOM\x10\x06\x12\x15\n" +
|
||||||
|
"\x11TASK_TYPE_GET_CET\x10\a*\x8a\x01\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"TaskStatus\x12\x17\n" +
|
"TaskStatus\x12\x17\n" +
|
||||||
"\x13TASK_STATUS_UNKNOWN\x10\x00\x12\x17\n" +
|
"\x13TASK_STATUS_UNKNOWN\x10\x00\x12\x17\n" +
|
||||||
@@ -2138,7 +2450,7 @@ func file_proto_runner_runner_proto_rawDescGZIP() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var file_proto_runner_runner_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
var file_proto_runner_runner_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
||||||
var file_proto_runner_runner_proto_msgTypes = make([]protoimpl.MessageInfo, 25)
|
var file_proto_runner_runner_proto_msgTypes = make([]protoimpl.MessageInfo, 29)
|
||||||
var file_proto_runner_runner_proto_goTypes = []any{
|
var file_proto_runner_runner_proto_goTypes = []any{
|
||||||
(TaskType)(0), // 0: runner.TaskType
|
(TaskType)(0), // 0: runner.TaskType
|
||||||
(TaskStatus)(0), // 1: runner.TaskStatus
|
(TaskStatus)(0), // 1: runner.TaskStatus
|
||||||
@@ -2166,7 +2478,11 @@ var file_proto_runner_runner_proto_goTypes = []any{
|
|||||||
(*GetEmptyClassroomPayload)(nil), // 23: runner.GetEmptyClassroomPayload
|
(*GetEmptyClassroomPayload)(nil), // 23: runner.GetEmptyClassroomPayload
|
||||||
(*EmptyClassroomResultData)(nil), // 24: runner.EmptyClassroomResultData
|
(*EmptyClassroomResultData)(nil), // 24: runner.EmptyClassroomResultData
|
||||||
(*EmptyClassroomEntry)(nil), // 25: runner.EmptyClassroomEntry
|
(*EmptyClassroomEntry)(nil), // 25: runner.EmptyClassroomEntry
|
||||||
nil, // 26: runner.RegisterRequest.CapabilitiesEntry
|
(*GetCetPayload)(nil), // 26: runner.GetCetPayload
|
||||||
|
(*CetScore)(nil), // 27: runner.CetScore
|
||||||
|
(*CetStudentInfo)(nil), // 28: runner.CetStudentInfo
|
||||||
|
(*CetResultData)(nil), // 29: runner.CetResultData
|
||||||
|
nil, // 30: runner.RegisterRequest.CapabilitiesEntry
|
||||||
}
|
}
|
||||||
var file_proto_runner_runner_proto_depIdxs = []int32{
|
var file_proto_runner_runner_proto_depIdxs = []int32{
|
||||||
3, // 0: runner.StreamMessage.register:type_name -> runner.RegisterRequest
|
3, // 0: runner.StreamMessage.register:type_name -> runner.RegisterRequest
|
||||||
@@ -2176,7 +2492,7 @@ var file_proto_runner_runner_proto_depIdxs = []int32{
|
|||||||
7, // 4: runner.StreamMessage.task:type_name -> runner.Task
|
7, // 4: runner.StreamMessage.task:type_name -> runner.Task
|
||||||
9, // 5: runner.StreamMessage.result:type_name -> runner.TaskResult
|
9, // 5: runner.StreamMessage.result:type_name -> runner.TaskResult
|
||||||
8, // 6: runner.StreamMessage.task_cancel:type_name -> runner.TaskCancel
|
8, // 6: runner.StreamMessage.task_cancel:type_name -> runner.TaskCancel
|
||||||
26, // 7: runner.RegisterRequest.capabilities:type_name -> runner.RegisterRequest.CapabilitiesEntry
|
30, // 7: runner.RegisterRequest.capabilities:type_name -> runner.RegisterRequest.CapabilitiesEntry
|
||||||
0, // 8: runner.Task.type:type_name -> runner.TaskType
|
0, // 8: runner.Task.type:type_name -> runner.TaskType
|
||||||
1, // 9: runner.TaskResult.status:type_name -> runner.TaskStatus
|
1, // 9: runner.TaskResult.status:type_name -> runner.TaskStatus
|
||||||
15, // 10: runner.ScheduleResultData.courses:type_name -> runner.Course
|
15, // 10: runner.ScheduleResultData.courses:type_name -> runner.Course
|
||||||
@@ -2185,13 +2501,15 @@ var file_proto_runner_runner_proto_depIdxs = []int32{
|
|||||||
17, // 13: runner.GradesResultData.gpa_summary:type_name -> runner.GpaSummary
|
17, // 13: runner.GradesResultData.gpa_summary:type_name -> runner.GpaSummary
|
||||||
21, // 14: runner.ExamsResultData.exams:type_name -> runner.Exam
|
21, // 14: runner.ExamsResultData.exams:type_name -> runner.Exam
|
||||||
25, // 15: runner.EmptyClassroomResultData.classrooms:type_name -> runner.EmptyClassroomEntry
|
25, // 15: runner.EmptyClassroomResultData.classrooms:type_name -> runner.EmptyClassroomEntry
|
||||||
2, // 16: runner.RunnerHub.Connect:input_type -> runner.StreamMessage
|
28, // 16: runner.CetResultData.student_info:type_name -> runner.CetStudentInfo
|
||||||
2, // 17: runner.RunnerHub.Connect:output_type -> runner.StreamMessage
|
27, // 17: runner.CetResultData.scores:type_name -> runner.CetScore
|
||||||
17, // [17:18] is the sub-list for method output_type
|
2, // 18: runner.RunnerHub.Connect:input_type -> runner.StreamMessage
|
||||||
16, // [16:17] is the sub-list for method input_type
|
2, // 19: runner.RunnerHub.Connect:output_type -> runner.StreamMessage
|
||||||
16, // [16:16] is the sub-list for extension type_name
|
19, // [19:20] is the sub-list for method output_type
|
||||||
16, // [16:16] is the sub-list for extension extendee
|
18, // [18:19] is the sub-list for method input_type
|
||||||
0, // [0:16] is the sub-list for field type_name
|
18, // [18:18] is the sub-list for extension type_name
|
||||||
|
18, // [18:18] is the sub-list for extension extendee
|
||||||
|
0, // [0:18] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_proto_runner_runner_proto_init() }
|
func init() { file_proto_runner_runner_proto_init() }
|
||||||
@@ -2214,7 +2532,7 @@ func file_proto_runner_runner_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_runner_runner_proto_rawDesc), len(file_proto_runner_runner_proto_rawDesc)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_runner_runner_proto_rawDesc), len(file_proto_runner_runner_proto_rawDesc)),
|
||||||
NumEnums: 2,
|
NumEnums: 2,
|
||||||
NumMessages: 25,
|
NumMessages: 29,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ enum TaskType {
|
|||||||
TASK_TYPE_GET_EXAMS = 4; // 获取考试安排
|
TASK_TYPE_GET_EXAMS = 4; // 获取考试安排
|
||||||
TASK_TYPE_GET_USER_INFO = 5; // 获取用户信息
|
TASK_TYPE_GET_USER_INFO = 5; // 获取用户信息
|
||||||
TASK_TYPE_GET_EMPTY_CLASSROOM = 6; // 获取空教室
|
TASK_TYPE_GET_EMPTY_CLASSROOM = 6; // 获取空教室
|
||||||
|
TASK_TYPE_GET_CET = 7; // 获取四六级成绩
|
||||||
}
|
}
|
||||||
|
|
||||||
// TaskStatus 任务状态枚举
|
// TaskStatus 任务状态枚举
|
||||||
@@ -208,6 +209,7 @@ message Grade {
|
|||||||
string score = 7; // 成绩 (可能是等级或分数)
|
string score = 7; // 成绩 (可能是等级或分数)
|
||||||
string grade_point = 8; // 绩点
|
string grade_point = 8; // 绩点
|
||||||
string is_exam = 9; // 是否考试课
|
string is_exam = 9; // 是否考试课
|
||||||
|
bool is_retake = 10; // 是否为补考
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExamsResultData 考试安排结果数据
|
// ExamsResultData 考试安排结果数据
|
||||||
@@ -264,3 +266,35 @@ message EmptyClassroomEntry {
|
|||||||
string term = 4; // 学期描述
|
string term = 4; // 学期描述
|
||||||
string weeks = 5; // 周次范围
|
string weeks = 5; // 周次范围
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCetPayload 获取四六级成绩任务载荷
|
||||||
|
message GetCetPayload {
|
||||||
|
string username = 1; // 学号
|
||||||
|
string password = 2; // 密码
|
||||||
|
}
|
||||||
|
|
||||||
|
// CetScore 四六级成绩条目
|
||||||
|
message CetScore {
|
||||||
|
string level = 1; // 等级(英语四级/英语六级)
|
||||||
|
string exam_time = 2; // 考试时间,如 2025年06月
|
||||||
|
string ticket_num = 3; // 准考证号
|
||||||
|
string score = 4; // 成绩
|
||||||
|
}
|
||||||
|
|
||||||
|
// CetStudentInfo 四六级查询页面的学生信息
|
||||||
|
message CetStudentInfo {
|
||||||
|
string student_id = 1; // 学号
|
||||||
|
string name = 2; // 姓名
|
||||||
|
string gender = 3; // 性别
|
||||||
|
string id_card = 4; // 身份证号
|
||||||
|
string duration = 5; // 学制
|
||||||
|
string grade = 6; // 年级
|
||||||
|
string college = 7; // 学院
|
||||||
|
string major = 8; // 专业
|
||||||
|
}
|
||||||
|
|
||||||
|
// CetResultData 四六级成绩结果数据
|
||||||
|
message CetResultData {
|
||||||
|
CetStudentInfo student_info = 1; // 学生信息
|
||||||
|
repeated CetScore scores = 2; // 成绩列表
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.2
|
// - protoc-gen-go-grpc v1.6.1
|
||||||
// - protoc v7.34.1
|
// - protoc v6.32.0
|
||||||
// source: proto/runner/runner.proto
|
// source: proto/runner/runner.proto
|
||||||
|
|
||||||
package runner
|
package runner
|
||||||
|
|||||||
Reference in New Issue
Block a user