feat: note scoring 60/6 with rating award + Minecraft theme

- Score max changed from 100 to 60, rating max from 10 to 6
- Note scoring now awards actual rating points (delta-based)
- Re-scoring only awards/deducts the difference
- Rating history shows note_score entries with problem link
- LLM prompt includes problem statement context for better evaluation
- LLM scoring dimensions: 题意理解/思路算法/代码记录/踩坑反思 (15 each)
- Minecraft-themed UI: 矿石鉴定, 探索笔记, 存入宝典, etc.
- Fallback scoring adjusted for 60-point scale
- Handle LLM markdown code fence wrapping in response

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
这个提交包含在:
cryptocommuniums-afk
2026-02-16 18:32:23 +08:00
父节点 7dd10bef2d
当前提交 9772ea6764
修改 7 个文件,包含 142 行新增46 行删除

查看文件

@@ -195,4 +195,59 @@ void WrongBookService::Remove(int64_t user_id, int64_t problem_id) {
sqlite3_finalize(stmt);
}
int32_t WrongBookService::GetNoteRating(int64_t user_id, int64_t problem_id) {
sqlite3* db = db_.raw();
sqlite3_stmt* stmt = nullptr;
const char* sql = "SELECT note_rating FROM wrong_book WHERE user_id=? AND problem_id=? LIMIT 1";
CheckSqlite(sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr), db,
"prepare get note_rating");
CheckSqlite(sqlite3_bind_int64(stmt, 1, user_id), db, "bind user_id");
CheckSqlite(sqlite3_bind_int64(stmt, 2, problem_id), db, "bind problem_id");
int32_t rating = 0;
if (sqlite3_step(stmt) == SQLITE_ROW) {
rating = sqlite3_column_int(stmt, 0);
}
sqlite3_finalize(stmt);
return rating;
}
void WrongBookService::AwardNoteRating(int64_t user_id, int64_t problem_id, int delta) {
sqlite3* db = db_.raw();
// Update user rating
{
sqlite3_stmt* stmt = nullptr;
const char* sql = "UPDATE users SET rating=rating+? WHERE id=?";
CheckSqlite(sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr), db,
"prepare add note rating");
CheckSqlite(sqlite3_bind_int(stmt, 1, delta), db, "bind delta");
CheckSqlite(sqlite3_bind_int64(stmt, 2, user_id), db, "bind user_id");
CheckSqlite(sqlite3_step(stmt), db, "exec add note rating");
sqlite3_finalize(stmt);
}
// Log to daily_task_logs for rating history visibility
{
sqlite3_stmt* stmt = nullptr;
const char* sql =
"INSERT INTO daily_task_logs(user_id,task_code,day_key,reward,created_at) "
"VALUES(?,?,?,?,?)";
CheckSqlite(sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr), db,
"prepare note rating log");
const std::string task_code = "note_score_" + std::to_string(problem_id);
const int64_t now = NowSec();
// Use a unique day_key to avoid IGNORE conflicts
const std::string day_key = "note_" + std::to_string(now);
CheckSqlite(sqlite3_bind_int64(stmt, 1, user_id), db, "bind user_id");
CheckSqlite(sqlite3_bind_text(stmt, 2, task_code.c_str(), -1, SQLITE_TRANSIENT), db,
"bind task_code");
CheckSqlite(sqlite3_bind_text(stmt, 3, day_key.c_str(), -1, SQLITE_TRANSIENT), db,
"bind day_key");
CheckSqlite(sqlite3_bind_int(stmt, 4, delta), db, "bind reward");
CheckSqlite(sqlite3_bind_int64(stmt, 5, now), db, "bind created_at");
CheckSqlite(sqlite3_step(stmt), db, "insert note rating log");
sqlite3_finalize(stmt);
}
}
} // namespace csp::services