syntax = "proto3"; package runner; option go_package = "schedule_converter/proto/runner;runner"; // ============================================================ // 服务定义 // ============================================================ // RunnerHub 服务 - 由 Backend 服务器实现 // Runner 作为客户端主动连接,建立双向流通信 service RunnerHub { // Connect 建立双向流连接 // Runner 通过此连接注册、接收任务、返回结果 rpc Connect(stream StreamMessage) returns (stream StreamMessage); } // ============================================================ // 流消息包装 - 所有消息通过 oneof 包装 // ============================================================ // StreamMessage 双向流消息包装 message StreamMessage { oneof message { RegisterRequest register = 1; // Runner 注册请求 RegisterResponse register_response = 2; // 注册响应 Heartbeat heartbeat = 3; // 心跳请求 HeartbeatAck heartbeat_ack = 4; // 心跳响应 Task task = 5; // 下发的任务 TaskResult result = 6; // 任务结果 TaskCancel task_cancel = 7; // 取消任务 } } // ============================================================ // 注册相关消息 // ============================================================ // RegisterRequest Runner 注册请求 message RegisterRequest { string runner_id = 1; // Runner 唯一标识 (UUID) string version = 2; // Runner 版本号 map capabilities = 3; // 能力标签 // 例如: {"login": "true", "schedule": "true", "grades": "true"} } // RegisterResponse 注册响应 message RegisterResponse { bool success = 1; // 是否成功 string session_id = 2; // 会话ID,用于标识本次连接 string message = 3; // 消息说明 int32 heartbeat_interval = 4; // 心跳间隔 (秒) int32 task_timeout = 5; // 默认任务超时时间 (秒) } // ============================================================ // 心跳消息 // ============================================================ // Heartbeat 心跳请求 message Heartbeat { int64 timestamp = 1; // 客户端时间戳 (毫秒) } // HeartbeatAck 心跳响应 message HeartbeatAck { int64 timestamp = 1; // 服务端时间戳 (毫秒) int64 latency = 2; // 往返延迟 (毫秒) } // ============================================================ // 任务定义 // ============================================================ // TaskType 任务类型枚举 enum TaskType { TASK_TYPE_UNKNOWN = 0; // 未知类型 TASK_TYPE_LOGIN = 1; // 登录验证 TASK_TYPE_GET_SCHEDULE = 2; // 获取课表 TASK_TYPE_GET_GRADES = 3; // 获取成绩 TASK_TYPE_GET_EXAMS = 4; // 获取考试安排 TASK_TYPE_GET_USER_INFO = 5; // 获取用户信息 TASK_TYPE_GET_EMPTY_CLASSROOM = 6; // 获取空教室 TASK_TYPE_GET_CET = 7; // 获取四六级成绩 } // TaskStatus 任务状态枚举 enum TaskStatus { TASK_STATUS_UNKNOWN = 0; // 未知状态 TASK_STATUS_SUCCESS = 1; // 成功 TASK_STATUS_FAILED = 2; // 失败 TASK_STATUS_TIMEOUT = 3; // 超时 TASK_STATUS_CANCELLED = 4; // 已取消 } // Task 任务定义 message Task { string task_id = 1; // 任务唯一ID (UUID) TaskType type = 2; // 任务类型 int64 created_at = 3; // 创建时间戳 (毫秒) int32 timeout_seconds = 4; // 超时时间 (秒) bytes payload = 5; // 任务载荷 (JSON 编码) } // TaskCancel 取消任务 message TaskCancel { string task_id = 1; // 要取消的任务ID string reason = 2; // 取消原因 } // TaskResult 任务结果 message TaskResult { string task_id = 1; // 任务ID TaskStatus status = 2; // 执行状态 int64 completed_at = 3; // 完成时间戳 (毫秒) bytes data = 4; // 结果数据 (JSON 编码) string error_code = 5; // 错误码 string error_message = 6; // 错误消息 } // ============================================================ // 任务载荷定义 - 用于 JSON 序列化到 bytes // ============================================================ // LoginPayload 登录任务载荷 message LoginPayload { string username = 1; // 学号 string password = 2; // 密码 string twfid = 3; // 初始 Cookie (可选) } // GetSchedulePayload 获取课表任务载荷 message GetSchedulePayload { string username = 1; // 学号 string password = 2; // 密码 string semester = 3; // 学期,如 "2025-20262" } // GetGradesPayload 获取成绩任务载荷 message GetGradesPayload { string username = 1; // 学号 string password = 2; // 密码 string semester = 3; // 学期 (可选,为空则获取全部) } // GetExamsPayload 获取考试安排任务载荷 message GetExamsPayload { string username = 1; // 学号 string password = 2; // 密码 string semester = 3; // 学期 } // ============================================================ // 结果数据定义 - 用于 JSON 序列化到 bytes // ============================================================ // ScheduleResultData 课表结果数据 message ScheduleResultData { string semester = 1; // 学期 string student_id = 2; // 学号 string student_name = 3; // 学生姓名 repeated Course courses = 4; // 课程列表 } // Course 课程信息 message Course { string code = 1; // 课程代码 string name = 2; // 课程名称 string teacher = 3; // 授课教师 string room = 4; // 教室 float credit = 5; // 学分 repeated ScheduleTime schedule = 6; // 上课时间安排 } // ScheduleTime 上课时间安排 message ScheduleTime { string day = 1; // 星期几,"0"-"6" 表示周日到周六 repeated int32 sections = 2; // 节次,如 [1, 2, 3] repeated int32 weeks = 3; // 周次,如 [1, 2, 3, 4, 5] } // GpaSummary 学分绩汇总信息 message GpaSummary { string average_gpa = 1; // 平均学分绩 string rank = 2; // 专业排名 string exam_total_gpa = 3; // 考试课学分绩 string exam_total_credits = 4; // 考试课学分数 string fail_credits = 5; // 考查课不及格学分 string semesters = 6; // 计算学期数 } // GradesResultData 成绩结果数据 message GradesResultData { string semester = 1; // 学期 string student_id = 2; // 学号 repeated Grade grades = 3; // 成绩列表 GpaSummary gpa_summary = 4; // 学分绩汇总 (可选) } // Grade 成绩信息 message Grade { string term = 1; // 学期 string course_code = 2; // 课程代码 string course_name = 3; // 课程名称 string nature = 4; // 课程性质 string category = 5; // 课程类别 string credit = 6; // 学分 string score = 7; // 成绩 (可能是等级或分数) string grade_point = 8; // 绩点 string is_exam = 9; // 是否考试课 bool is_retake = 10; // 是否为补考 } // ExamsResultData 考试安排结果数据 message ExamsResultData { string semester = 1; // 学期 string student_id = 2; // 学号 repeated Exam exams = 3; // 考试列表 } // Exam 考试信息 message Exam { string course_name = 1; // 课程名称 string exam_type = 2; // 考试类型 (期末/期中/补考) string date = 3; // 考试日期 string time = 4; // 考试时间 string week = 5; // 考试周次 string weekday = 6; // 星期几 } // UserInfoResultData 用户信息结果数据 message UserInfoResultData { string student_id = 1; // 学号 string name = 2; // 姓名 string gender = 3; // 性别 string college = 4; // 学院 string major = 5; // 专业 string class_name = 6; // 班级 string grade = 7; // 年级 } // GetEmptyClassroomPayload 获取空教室任务载荷 message GetEmptyClassroomPayload { string username = 1; // 学号 string password = 2; // 密码 string semester = 3; // 学期 string week_start = 4; // 起始周次 string week_end = 5; // 结束周次 string campus_code = 6; // 校区代码 string building_code = 7; // 楼号代码(可选) } // EmptyClassroomResultData 空教室结果数据 message EmptyClassroomResultData { string semester = 1; // 学期 string student_id = 2; // 学号 repeated EmptyClassroomEntry classrooms = 3; // 空教室列表 } // EmptyClassroomEntry 空教室条目 message EmptyClassroomEntry { string classroom = 1; // 教室名称 string weekday = 2; // 星期几 string periods = 3; // 可用节次 string term = 4; // 学期描述 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; // 成绩列表 }