初步實作出刀紀錄表
This commit is contained in:
+43
@@ -0,0 +1,43 @@
|
||||
package club.sakunadaisuki.pcrediveclanrecordbackend.database.dto
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.bson.Document
|
||||
import java.time.Instant
|
||||
|
||||
@Serializable
|
||||
data class BattleRecordDto(
|
||||
val date: String, // yyyy-MM-dd
|
||||
var uid: String,
|
||||
@SerialName("player_name") val playerName: String,
|
||||
@SerialName("discord_name") val discordName: String,
|
||||
@SerialName("discord_id") val discordID: String,
|
||||
@SerialName("attack_detail_list") val attackDetailList: List<AttackDetailDto>
|
||||
) {
|
||||
fun toDocument(): Document = Document.parse(Json.encodeToString(this))
|
||||
|
||||
companion object {
|
||||
private val json = Json { ignoreUnknownKeys = true }
|
||||
|
||||
fun fromDocument(document: Document): BattleRecordDto = json.decodeFromString(document.toJson())
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class AttackDetailDto(
|
||||
@SerialName("boss_round") val bossRound: Int, // 周目
|
||||
@SerialName("boss_index") val bossIndex: Int, // 1~5 號王
|
||||
val damage: Long, // 傷害
|
||||
@SerialName("is_compensation") val isCompensation: Boolean = false, // true: 補償刀, false: 正刀
|
||||
@SerialName("created_at") val createdAt: Long = Instant.now().toEpochMilli(),
|
||||
@SerialName("updated_at") val updatedAt: Long = Instant.now().toEpochMilli()
|
||||
) {
|
||||
fun toDocument(): Document = Document.parse(Json.encodeToString(this))
|
||||
|
||||
companion object {
|
||||
private val json = Json { ignoreUnknownKeys = true }
|
||||
|
||||
fun fromDocument(document: Document): AttackDetailDto = json.decodeFromString(document.toJson())
|
||||
}
|
||||
}
|
||||
+7
-5
@@ -1,18 +1,20 @@
|
||||
package club.sakunadaisuki.pcrediveclanrecordbackend.database.dto
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.bson.Document
|
||||
import java.time.Instant
|
||||
|
||||
@Serializable
|
||||
data class MemberDto(
|
||||
var uid: String,
|
||||
val playerName: String,
|
||||
val nickName: String,
|
||||
val discordID: String,
|
||||
@SerialName("player_name") val playerName: String,
|
||||
@SerialName("discord_name") val discordName: String,
|
||||
@SerialName("discord_id") val discordID: String,
|
||||
var leave: Boolean = false,
|
||||
var createAt: Long? = null,
|
||||
var updatedAt: Long? = null
|
||||
@SerialName("created_at") var createAt: Long? = null,
|
||||
@SerialName("updated_at") var updatedAt: Long? = null
|
||||
) {
|
||||
fun toDocument(): Document = Document.parse(Json.encodeToString(this))
|
||||
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package club.sakunadaisuki.pcrediveclanrecordbackend.database.service
|
||||
|
||||
import club.sakunadaisuki.pcrediveclanrecordbackend.database.dto.BattleRecordDto
|
||||
import com.mongodb.client.MongoCollection
|
||||
import com.mongodb.client.MongoDatabase
|
||||
import com.mongodb.client.model.Filters
|
||||
import com.mongodb.client.model.Filters.and
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.bson.Document
|
||||
|
||||
class BattleRecordService(private val database: MongoDatabase) {
|
||||
var collection: MongoCollection<Document>
|
||||
|
||||
init {
|
||||
database.createCollection("battle_records")
|
||||
collection = database.getCollection("battle_records")
|
||||
}
|
||||
|
||||
// Create new car
|
||||
suspend fun create(data: BattleRecordDto): String = withContext(Dispatchers.IO) {
|
||||
val doc = data.toDocument()
|
||||
collection.insertOne(doc)
|
||||
doc["uid"].toString()
|
||||
}
|
||||
|
||||
// Read a car
|
||||
suspend fun read(date: String): List<BattleRecordDto> = withContext(Dispatchers.IO) {
|
||||
collection.find(Filters.eq("date", date)).toList().map(BattleRecordDto::fromDocument)
|
||||
}
|
||||
|
||||
// Read a car
|
||||
suspend fun read(date: String, uid: String): BattleRecordDto? = withContext(Dispatchers.IO) {
|
||||
val filter = and(
|
||||
Filters.eq("date", date),
|
||||
Filters.eq("uid", uid)
|
||||
)
|
||||
collection.find(filter).first()?.let(BattleRecordDto::fromDocument)
|
||||
}
|
||||
|
||||
// Update a car
|
||||
suspend fun update(date: String, data: BattleRecordDto): Document? = withContext(Dispatchers.IO) {
|
||||
val filter = and(
|
||||
Filters.eq("date", date),
|
||||
Filters.eq("uid", data.uid)
|
||||
)
|
||||
collection.findOneAndReplace(filter, data.toDocument())
|
||||
}
|
||||
|
||||
// Delete a car
|
||||
suspend fun delete(date: String, uid: String): Document? = withContext(Dispatchers.IO) {
|
||||
val filter = and(
|
||||
Filters.eq("date", date),
|
||||
Filters.eq("uid", uid)
|
||||
)
|
||||
collection.findOneAndDelete(filter)
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -16,7 +16,7 @@ class MemberService(private val database: MongoDatabase) {
|
||||
collection = database.getCollection("member")
|
||||
}
|
||||
|
||||
// Create new car
|
||||
// Create new member
|
||||
suspend fun create(data: MemberDto): String = withContext(Dispatchers.IO) {
|
||||
data.createAt = System.currentTimeMillis()
|
||||
data.updatedAt = System.currentTimeMillis()
|
||||
@@ -26,22 +26,22 @@ class MemberService(private val database: MongoDatabase) {
|
||||
doc["uid"].toString()
|
||||
}
|
||||
|
||||
// Read a car
|
||||
// Read a member
|
||||
suspend fun read(): List<MemberDto> = withContext(Dispatchers.IO) {
|
||||
collection.find().toList().map(MemberDto::fromDocument)
|
||||
}
|
||||
|
||||
// Read a car
|
||||
// Read a member
|
||||
suspend fun read(uid: String): MemberDto? = withContext(Dispatchers.IO) {
|
||||
collection.find(Filters.eq("uid", uid)).first()?.let(MemberDto::fromDocument)
|
||||
}
|
||||
|
||||
// Update a car
|
||||
// Update a member
|
||||
suspend fun update(uid: String, data: MemberDto): Document? = withContext(Dispatchers.IO) {
|
||||
collection.findOneAndReplace(Filters.eq("uid", uid), data.toDocument())
|
||||
}
|
||||
|
||||
// Delete a car
|
||||
// Delete a member
|
||||
suspend fun delete(uid: String): Document? = withContext(Dispatchers.IO) {
|
||||
collection.findOneAndDelete(Filters.eq("uid", uid))
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package club.sakunadaisuki.pcrediveclanrecordbackend.mapper
|
||||
|
||||
import club.sakunadaisuki.pcrediveclanrecordbackend.database.dto.AttackDetailDto
|
||||
import club.sakunadaisuki.pcrediveclanrecordbackend.database.dto.BattleRecordDto
|
||||
import club.sakunadaisuki.pcrediveclanrecordbackend.model.AttackDetail
|
||||
import club.sakunadaisuki.pcrediveclanrecordbackend.model.BattleRecord
|
||||
|
||||
fun BattleRecord.toDto(): BattleRecordDto = BattleRecordDto(
|
||||
date = date,
|
||||
uid = uid,
|
||||
playerName = playerName,
|
||||
discordName = discordName,
|
||||
discordID = discordID,
|
||||
attackDetailList = attackDetailList.map { it.toDto() },
|
||||
)
|
||||
|
||||
fun AttackDetail.toDto(): AttackDetailDto = AttackDetailDto(
|
||||
bossRound = bossRound,
|
||||
bossIndex = bossIndex,
|
||||
damage = damage,
|
||||
isCompensation = isCompensation,
|
||||
createdAt = createdAt,
|
||||
updatedAt = updatedAt,
|
||||
)
|
||||
@@ -7,7 +7,7 @@ fun Member.toDto(): MemberDto {
|
||||
return MemberDto(
|
||||
uid = uid,
|
||||
playerName = playerName,
|
||||
nickName = nickName,
|
||||
discordName = discordName,
|
||||
discordID = discordID,
|
||||
leave = leave,
|
||||
createAt = createAt,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package club.sakunadaisuki.pcrediveclanrecordbackend.model
|
||||
|
||||
import java.time.Instant
|
||||
|
||||
data class BattleRecord(
|
||||
val date: String, // yyyy-MM-dd
|
||||
var uid: String,
|
||||
val playerName: String,
|
||||
val discordName: String,
|
||||
val discordID: String,
|
||||
val attackDetailList: List<AttackDetail>
|
||||
)
|
||||
|
||||
data class AttackDetail(
|
||||
val bossRound: Int, // 周目
|
||||
val bossIndex: Int, // 1~5 號王
|
||||
val damage: Long, // 傷害
|
||||
val isCompensation: Boolean = false, // true: 補償刀, false: 正刀
|
||||
val createdAt: Long = Instant.now().toEpochMilli(),
|
||||
val updatedAt: Long = Instant.now().toEpochMilli()
|
||||
)
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package club.sakunadaisuki.pcrediveclanrecordbackend.model
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class BattleRecordRequest(
|
||||
val date: String,
|
||||
val uid: String,
|
||||
@SerialName("player_name") val name: String,
|
||||
@SerialName("discord_name") val discordName: String,
|
||||
@SerialName("discord_id") val discordID: String,
|
||||
val round: Int,
|
||||
val boss: Int,
|
||||
val damage: Long,
|
||||
@SerialName("is_compensation") val isCompensation: Boolean = false,
|
||||
)
|
||||
@@ -3,7 +3,7 @@ package club.sakunadaisuki.pcrediveclanrecordbackend.model
|
||||
data class Member(
|
||||
var uid: String,
|
||||
val playerName: String,
|
||||
val nickName: String,
|
||||
val discordName: String,
|
||||
val discordID: String,
|
||||
var leave: Boolean = false,
|
||||
var createAt: Long? = null,
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package club.sakunadaisuki.pcrediveclanrecordbackend.plugins
|
||||
|
||||
import club.sakunadaisuki.pcrediveclanrecordbackend.database.dto.BattleRecordDto
|
||||
import club.sakunadaisuki.pcrediveclanrecordbackend.database.service.BattleRecordService
|
||||
import club.sakunadaisuki.pcrediveclanrecordbackend.model.Member
|
||||
import club.sakunadaisuki.pcrediveclanrecordbackend.database.service.MemberService
|
||||
import club.sakunadaisuki.pcrediveclanrecordbackend.mapper.toDto
|
||||
import club.sakunadaisuki.pcrediveclanrecordbackend.model.AttackDetail
|
||||
import club.sakunadaisuki.pcrediveclanrecordbackend.model.BattleRecordRequest
|
||||
import com.mongodb.client.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.server.application.*
|
||||
@@ -17,20 +21,23 @@ fun Application.configureMongo() {
|
||||
val memberService = runCatching {
|
||||
MemberService(mongoDatabase)
|
||||
}.getOrNull() ?: return
|
||||
val battleRecordService = runCatching {
|
||||
BattleRecordService(mongoDatabase)
|
||||
}.getOrNull() ?: return
|
||||
|
||||
routing {
|
||||
route("/api") {
|
||||
// Read member
|
||||
get("/member") {
|
||||
memberService.read().let { member ->
|
||||
call.respond(member)
|
||||
call.respond(HttpStatusCode.OK, member)
|
||||
}
|
||||
}
|
||||
// Read member
|
||||
get("/member/{uid}") {
|
||||
val uid = call.parameters["uid"] ?: throw IllegalArgumentException("No ID found")
|
||||
memberService.read(uid)?.let { member ->
|
||||
call.respond(member)
|
||||
call.respond(HttpStatusCode.OK, member)
|
||||
} ?: call.respond(HttpStatusCode.NotFound)
|
||||
}
|
||||
// Create member
|
||||
@@ -56,6 +63,45 @@ fun Application.configureMongo() {
|
||||
}
|
||||
|
||||
// TODO Battle Record
|
||||
get("/battle_record/{date}") {
|
||||
val date = call.parameters["date"] ?: throw IllegalArgumentException("No date")
|
||||
battleRecordService.read(date).let { battleRecord ->
|
||||
call.respond(HttpStatusCode.OK, battleRecord)
|
||||
}
|
||||
}
|
||||
|
||||
post("/battle_record") {
|
||||
val request = call.receive<BattleRecordRequest>()
|
||||
val newAttackDetail = AttackDetail(
|
||||
bossRound = request.round,
|
||||
bossIndex = request.boss,
|
||||
damage = request.damage,
|
||||
isCompensation = request.isCompensation,
|
||||
)
|
||||
val existData = battleRecordService.read(request.date, request.uid)
|
||||
if (existData != null) {
|
||||
val attackDetails = existData.attackDetailList.toMutableList()
|
||||
attackDetails.add(newAttackDetail.toDto())
|
||||
val newData = existData.copy(
|
||||
attackDetailList = attackDetails
|
||||
)
|
||||
battleRecordService.update(request.date, newData)?.let {
|
||||
call.respond(HttpStatusCode.OK, it)
|
||||
} ?: call.respond(HttpStatusCode.NotFound)
|
||||
} else {
|
||||
val newData = BattleRecordDto(
|
||||
date = request.date,
|
||||
uid = request.uid,
|
||||
playerName = request.name,
|
||||
discordName = request.discordName,
|
||||
discordID = request.discordID,
|
||||
attackDetailList = listOf(newAttackDetail.toDto())
|
||||
)
|
||||
val id = battleRecordService.create(newData)
|
||||
call.respond(HttpStatusCode.Created, id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user