tag(功能):加入按照房间名称加入的功能

This commit is contained in:
OrangeRoll
2026-08-07 14:12:36 +08:00
parent 9c0a4f59f6
commit d00848ee36
5 changed files with 126 additions and 6 deletions
@@ -206,6 +206,24 @@ object RoomRepository {
}
}
fun findByTitle(title: String): RoomRecord? = Database.useConnection { connection ->
connection.prepareStatement(
"SELECT id, title, status, created_by FROM rooms WHERE LOWER(title) = LOWER(?)",
).use { statement ->
statement.setString(1, title)
statement.executeQuery().use { result ->
if (result.next()) {
RoomRecord(
result.getObject("id", UUID::class.java),
result.getString("title"),
result.getString("status"),
result.getObject("created_by", UUID::class.java),
)
} else null
}
}
}
fun member(roomId: UUID, userId: UUID): RoomMember? = Database.useConnection { connection ->
connection.prepareStatement(
"SELECT room_id, user_id, role FROM room_members WHERE room_id = ? AND user_id = ?",
@@ -105,6 +105,7 @@ fun Application.configureRouting() {
val user = call.requireCurrentUser()
val title = call.receive<CreateRoomRequest>().title.trim()
if (title.length !in 1..128) throw ApiException("房间标题必须为 1-128 个字符", 400)
if (RoomRepository.findByTitle(title) != null) throw ApiException("该房间标题已存在", 409)
call.respond(HttpStatusCode.Created, RoomResponse(RoomRepository.create(user.id, title), RoomRole.host))
}
@@ -121,6 +122,15 @@ fun Application.configureRouting() {
call.respond(RoomMemberResponse(RoomRepository.joinAsViewer(call.roomId(), user.id)))
}
post("/api/rooms/join-by-title") {
val user = call.requireCurrentUser()
val title = call.receive<FindRoomByTitleRequest>().title.trim()
if (title.isEmpty()) throw ApiException("请输入房间标题", 400)
val room = RoomRepository.findByTitle(title) ?: throw ApiException("未找到该房间", 404)
val membership = RoomRepository.joinAsViewer(room.id, user.id)
call.respond(RoomResponse(room, membership.role))
}
post("/api/rooms/{roomId}/members/{userId}/role") {
val requester = call.requireCurrentUser()
val roomId = call.roomId()
@@ -214,6 +224,7 @@ enum class RoomRole { host, publisher, viewer }
@Serializable data class RegisterRequest(val inviteCode: String, val username: String, val password: String, val displayName: String)
@Serializable data class CreateInvitationRequest(val type: String, val expiresInHours: Int = 168)
@Serializable data class CreateRoomRequest(val title: String)
@Serializable data class FindRoomByTitleRequest(val title: String)
@Serializable data class UpdateMemberRoleRequest(val role: String)
@Serializable data class AuthResponse(val token: String, val user: UserResponse)
@Serializable data class UserResponse(val id: String, val username: String, val displayName: String, val isAdmin: Boolean) {
@@ -0,0 +1 @@
CREATE UNIQUE INDEX uq_rooms_title_case_insensitive ON rooms (LOWER(title));