feat: ship minecraft theme updates and platform workflow improvements
这个提交包含在:
@@ -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
|
||||
|
||||
在新工单中引用
屏蔽一个用户