feat: ship minecraft theme updates and platform workflow improvements

这个提交包含在:
Codex CLI
2026-02-15 17:36:56 +08:00
父节点 cd7540ab9d
当前提交 37266bb846
修改 32 个文件,包含 5297 行新增119 行删除

查看文件

@@ -13,6 +13,9 @@ class AdminController : public drogon::HttpController<AdminController> {
ADD_METHOD_TO(AdminController::updateUserRating,
"/api/v1/admin/users/{1}/rating",
drogon::Patch);
ADD_METHOD_TO(AdminController::deleteUser,
"/api/v1/admin/users/{1}",
drogon::Delete);
ADD_METHOD_TO(AdminController::listRedeemItems, "/api/v1/admin/redeem-items", drogon::Get);
ADD_METHOD_TO(AdminController::createRedeemItem, "/api/v1/admin/redeem-items", drogon::Post);
ADD_METHOD_TO(AdminController::updateRedeemItem,
@@ -32,6 +35,9 @@ class AdminController : public drogon::HttpController<AdminController> {
void updateUserRating(const drogon::HttpRequestPtr& req,
std::function<void(const drogon::HttpResponsePtr&)>&& cb,
int64_t user_id);
void deleteUser(const drogon::HttpRequestPtr& req,
std::function<void(const drogon::HttpResponsePtr&)>&& cb,
int64_t user_id);
void listRedeemItems(const drogon::HttpRequestPtr& req,
std::function<void(const drogon::HttpResponsePtr&)>&& cb);

查看文件

@@ -22,6 +22,7 @@ class UserService {
std::vector<domain::GlobalLeaderboardEntry> GlobalLeaderboard(int limit = 100);
UserListResult ListUsers(int page, int page_size);
void SetRating(int64_t user_id, int rating);
void DeleteUser(int64_t user_id);
private:
db::SqliteDb& db_;

查看文件

@@ -192,6 +192,42 @@ void AdminController::updateUserRating(
}
}
void AdminController::deleteUser(
const drogon::HttpRequestPtr& req,
std::function<void(const drogon::HttpResponsePtr&)>&& cb,
int64_t user_id) {
try {
const auto admin_user_id = RequireAdminUserId(req, cb);
if (!admin_user_id.has_value()) return;
if (*admin_user_id == user_id) {
cb(JsonError(drogon::k400BadRequest, "cannot delete current admin user"));
return;
}
services::UserService users(csp::AppState::Instance().db());
const auto target = users.GetById(user_id);
if (!target.has_value()) {
cb(JsonError(drogon::k404NotFound, "user not found"));
return;
}
if (target->username == "admin") {
cb(JsonError(drogon::k400BadRequest, "cannot delete reserved admin user"));
return;
}
users.DeleteUser(user_id);
Json::Value payload;
payload["id"] = Json::Int64(user_id);
payload["username"] = target->username;
payload["deleted"] = true;
cb(JsonOk(payload));
} catch (const std::exception& e) {
cb(JsonError(drogon::k500InternalServerError, e.what()));
}
}
void AdminController::listRedeemItems(
const drogon::HttpRequestPtr& req,
std::function<void(const drogon::HttpResponsePtr&)>&& cb) {

查看文件

@@ -100,6 +100,7 @@ Json::Value BuildOpenApiSpec() {
paths["/api/v1/submissions/{id}/analysis"]["post"]["summary"] = "提交评测建议LLM";
paths["/api/v1/admin/users"]["get"]["summary"] = "管理员用户列表";
paths["/api/v1/admin/users/{id}/rating"]["patch"]["summary"] = "管理员修改用户积分";
paths["/api/v1/admin/users/{id}"]["delete"]["summary"] = "管理员删除用户";
paths["/api/v1/admin/redeem-items"]["get"]["summary"] = "管理员查看积分兑换物品";
paths["/api/v1/admin/redeem-items"]["post"]["summary"] = "管理员新增积分兑换物品";
paths["/api/v1/admin/redeem-items/{id}"]["patch"]["summary"] = "管理员修改积分兑换物品";

查看文件

@@ -138,7 +138,13 @@ void ProblemController::getDraft(
services::ProblemWorkspaceService svc(csp::AppState::Instance().db());
const auto draft = svc.GetDraft(*user_id, problem_id);
if (!draft.has_value()) {
cb(JsonError(drogon::k404NotFound, "draft not found"));
Json::Value payload;
payload["language"] = "cpp";
payload["code"] = "";
payload["stdin"] = "";
payload["updated_at"] = Json::nullValue;
payload["exists"] = false;
cb(JsonOk(payload));
return;
}
@@ -147,6 +153,7 @@ void ProblemController::getDraft(
payload["code"] = draft->code;
payload["stdin"] = draft->stdin_text;
payload["updated_at"] = Json::Int64(draft->updated_at);
payload["exists"] = true;
cb(JsonOk(payload));
} catch (const std::exception& e) {
cb(JsonError(drogon::k500InternalServerError, e.what()));

查看文件

@@ -126,4 +126,18 @@ void UserService::SetRating(int64_t user_id, int rating) {
if (sqlite3_changes(db) <= 0) throw std::runtime_error("user not found");
}
void UserService::DeleteUser(int64_t user_id) {
if (user_id <= 0) throw std::runtime_error("invalid user_id");
sqlite3* db = db_.raw();
sqlite3_stmt* stmt = nullptr;
const char* sql = "DELETE FROM users WHERE id=?";
CheckSqlite(sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr), db,
"prepare delete user");
CheckSqlite(sqlite3_bind_int64(stmt, 1, user_id), db, "bind user_id");
CheckSqlite(sqlite3_step(stmt), db, "exec delete user");
sqlite3_finalize(stmt);
if (sqlite3_changes(db) <= 0) throw std::runtime_error("user not found");
}
} // namespace csp::services