實作CRUD
This commit is contained in:
parent
f288fb7c4b
commit
3e92de1609
@ -0,0 +1,40 @@
|
||||
package com.ray650128.pcredive.database.dto
|
||||
|
||||
import com.ray650128.pcredive.database.model.Member
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class MemberDto(
|
||||
var _id: String? = null,
|
||||
var playerName: String,
|
||||
var nickName: String,
|
||||
var discordID: String,
|
||||
var uid: String,
|
||||
var leave: Boolean = false,
|
||||
var createAt: Long? = null,
|
||||
var updatedAt: Long? = null
|
||||
)
|
||||
|
||||
fun Member.toDto(): MemberDto {
|
||||
return MemberDto(
|
||||
_id = this._id.toString(),
|
||||
playerName = this.playerName,
|
||||
nickName = this.nickName,
|
||||
discordID = this.discordID,
|
||||
uid = this.uid,
|
||||
leave = this.leave,
|
||||
createAt = this.createAt,
|
||||
updatedAt = this.updatedAt
|
||||
)
|
||||
}
|
||||
|
||||
fun MemberDto.toMember(): Member =
|
||||
Member(
|
||||
playerName = this.playerName,
|
||||
nickName = this.nickName,
|
||||
discordID = this.discordID,
|
||||
uid = this.uid,
|
||||
leave = this.leave,
|
||||
createAt = this.createAt,
|
||||
updatedAt = this.updatedAt
|
||||
)
|
||||
@ -0,0 +1,49 @@
|
||||
package com.ray650128.pcredive.database.dto
|
||||
|
||||
import com.ray650128.pcredive.database.model.Member
|
||||
import com.ray650128.pcredive.database.model.MemberRecord
|
||||
import com.ray650128.pcredive.database.model.Record
|
||||
import com.ray650128.pcredive.database.service.MemberService
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class MemberRecordDto(
|
||||
var _id: String? = null,
|
||||
var member: Member? = null,
|
||||
var record1: Record,
|
||||
var record1c: Record,
|
||||
var record2: Record,
|
||||
var record2c: Record,
|
||||
var record3: Record,
|
||||
var record3c: Record,
|
||||
var createdAt: Long?,
|
||||
var updatedAt: Long?
|
||||
)
|
||||
|
||||
fun MemberRecord.toDto(): MemberRecordDto {
|
||||
return MemberRecordDto(
|
||||
_id = this._id.toString(),
|
||||
member = MemberService.findById(this.memberId.toString()),
|
||||
record1 = this.record1,
|
||||
record1c = this.record1c,
|
||||
record2 = this.record2,
|
||||
record2c = this.record2c,
|
||||
record3 = this.record3,
|
||||
record3c = this.record3c,
|
||||
createdAt = this.createdAt,
|
||||
updatedAt = this.updatedAt
|
||||
)
|
||||
}
|
||||
|
||||
fun MemberRecordDto.toMemberRecord(): MemberRecord =
|
||||
MemberRecord(
|
||||
memberId = this.member?._id,
|
||||
record1 = this.record1,
|
||||
record1c = this.record1c,
|
||||
record2 = this.record2,
|
||||
record2c = this.record2c,
|
||||
record3 = this.record3,
|
||||
record3c = this.record3c,
|
||||
createdAt = this.createdAt,
|
||||
updatedAt = this.updatedAt
|
||||
)
|
||||
@ -0,0 +1,18 @@
|
||||
package com.ray650128.pcredive.database.model
|
||||
|
||||
import kotlinx.serialization.Contextual
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.litote.kmongo.Id
|
||||
import org.litote.kmongo.newId
|
||||
|
||||
@Serializable
|
||||
data class Member(
|
||||
@Contextual var _id: Id<Member> = newId(),
|
||||
var playerName: String,
|
||||
var nickName: String,
|
||||
var discordID: String,
|
||||
var uid: String,
|
||||
var leave: Boolean = false,
|
||||
var createAt: Long? = null,
|
||||
var updatedAt: Long? = null
|
||||
)
|
||||
@ -0,0 +1,26 @@
|
||||
package com.ray650128.pcredive.database.model
|
||||
|
||||
import kotlinx.serialization.Contextual
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.litote.kmongo.Id
|
||||
import org.litote.kmongo.newId
|
||||
|
||||
@Serializable
|
||||
data class MemberRecord(
|
||||
@Contextual var _id: Id<MemberRecord> = newId(),
|
||||
@Contextual var memberId: Id<Member>? = null,
|
||||
var record1: Record = Record("未出"),
|
||||
var record1c: Record = Record("未出"),
|
||||
var record2: Record = Record("未出"),
|
||||
var record2c: Record = Record("未出"),
|
||||
var record3: Record = Record("未出"),
|
||||
var record3c: Record = Record("未出"),
|
||||
var createdAt: Long? = null,
|
||||
var updatedAt: Long? = null
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Record(
|
||||
var boss: String,
|
||||
var damage: Int? = null
|
||||
)
|
||||
@ -0,0 +1,9 @@
|
||||
package com.ray650128.pcredive.database.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class RecordData(
|
||||
val member: Member,
|
||||
var record: MemberRecord
|
||||
)
|
||||
@ -0,0 +1,16 @@
|
||||
package com.ray650128.pcredive.database.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class UpdateMemberRecord(
|
||||
var memberId: String,
|
||||
var record1: Record = Record("未出"),
|
||||
var record1c: Record = Record("未出"),
|
||||
var record2: Record = Record("未出"),
|
||||
var record2c: Record = Record("未出"),
|
||||
var record3: Record = Record("未出"),
|
||||
var record3c: Record = Record("未出"),
|
||||
var createdAt: Long? = null,
|
||||
var updatedAt: Long? = null
|
||||
)
|
||||
@ -0,0 +1,53 @@
|
||||
package com.ray650128.pcredive.database.service
|
||||
|
||||
import com.ray650128.pcredive.database.model.Member
|
||||
import com.ray650128.pcredive.database.model.MemberRecord
|
||||
import org.bson.types.ObjectId
|
||||
import org.litote.kmongo.*
|
||||
import org.litote.kmongo.id.toId
|
||||
|
||||
object MemberRecordService {
|
||||
private val client = KMongo.createClient("mongodb://ray650128:Zx650128!@www.ray650128.com:27017")
|
||||
private val database = client.getDatabase("pc_re_dive_clan_battle")
|
||||
private val recordCollection = database.getCollection<MemberRecord>()
|
||||
|
||||
fun create(record: MemberRecord): Id<MemberRecord> {
|
||||
recordCollection.insertOne(record)
|
||||
return record._id
|
||||
}
|
||||
|
||||
fun findById(id: String): MemberRecord? {
|
||||
val bsonId: Id<MemberRecord> = ObjectId(id).toId()
|
||||
return recordCollection.findOne(MemberRecord::_id eq bsonId)
|
||||
}
|
||||
|
||||
fun findByTimeBetween(start: Long, end: Long): List<MemberRecord> {
|
||||
return recordCollection.find(MemberRecord::createdAt gte start, MemberRecord::createdAt lt end).toList()
|
||||
}
|
||||
|
||||
fun findByOwnerId(id: String): List<MemberRecord> {
|
||||
val bsonId: Id<Member> = ObjectId(id).toId()
|
||||
return recordCollection.find(MemberRecord::memberId eq bsonId).toList()
|
||||
}
|
||||
|
||||
fun updateById(id: String, request: MemberRecord): Boolean =
|
||||
findById(id)?.let { record ->
|
||||
val updateResult = recordCollection.replaceOne(
|
||||
record.copy(
|
||||
record1 = request.record1,
|
||||
record1c = request.record1c,
|
||||
record2 = request.record2,
|
||||
record2c = request.record2c,
|
||||
record3 = request.record3,
|
||||
record3c = request.record3c,
|
||||
updatedAt = System.currentTimeMillis()
|
||||
)
|
||||
)
|
||||
updateResult.modifiedCount == 1L
|
||||
} ?: false
|
||||
|
||||
fun deleteById(id: String): Boolean {
|
||||
val deleteResult = recordCollection.deleteOneById(ObjectId(id))
|
||||
return deleteResult.deletedCount == 1L
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package com.ray650128.pcredive.database.service
|
||||
|
||||
import com.ray650128.pcredive.database.model.Member
|
||||
import org.bson.types.ObjectId
|
||||
import org.litote.kmongo.*
|
||||
import org.litote.kmongo.id.toId
|
||||
|
||||
object MemberService {
|
||||
private val client = KMongo.createClient("mongodb://ray650128:Zx650128!@www.ray650128.com:27017")
|
||||
private val database = client.getDatabase("pc_re_dive_clan_battle")
|
||||
private val memberCollection = database.getCollection<Member>()
|
||||
|
||||
fun create(member: Member): Id<Member> {
|
||||
memberCollection.insertOne(member)
|
||||
return member._id
|
||||
}
|
||||
|
||||
//fun findAll(): List<Member> = memberCollection.find().toList()
|
||||
|
||||
fun findAll(isLeave: Boolean? = null): List<Member> {
|
||||
return if (isLeave == null) {
|
||||
memberCollection.find().toList()
|
||||
} else {
|
||||
memberCollection.find(Member::leave eq isLeave).toList()
|
||||
}
|
||||
}
|
||||
|
||||
fun findById(id: String): Member? {
|
||||
val bsonId: Id<Member> = ObjectId(id).toId()
|
||||
return memberCollection.findOne(Member::_id eq bsonId)
|
||||
}
|
||||
|
||||
fun updateById(id: String, request: Member): Boolean =
|
||||
findById(id)?.let { member ->
|
||||
val updateResult = memberCollection.replaceOne(
|
||||
member.copy(
|
||||
playerName = request.playerName,
|
||||
nickName = request.nickName,
|
||||
discordID = request.discordID,
|
||||
uid = request.uid,
|
||||
leave = request.leave,
|
||||
updatedAt = request.updatedAt
|
||||
)
|
||||
)
|
||||
updateResult.modifiedCount == 1L
|
||||
} ?: false
|
||||
|
||||
fun deleteById(id: String): Boolean {
|
||||
val deleteResult = memberCollection.deleteOneById(ObjectId(id))
|
||||
return deleteResult.deletedCount == 1L
|
||||
}
|
||||
}
|
||||
@ -1,15 +1,119 @@
|
||||
package com.ray650128.pcredive.plugins
|
||||
|
||||
import com.ray650128.pcredive.database.dto.toDto
|
||||
import com.ray650128.pcredive.database.model.MemberRecord
|
||||
import com.ray650128.pcredive.database.model.Record
|
||||
import com.ray650128.pcredive.database.model.RecordData
|
||||
import com.ray650128.pcredive.database.model.UpdateMemberRecord
|
||||
import com.ray650128.pcredive.database.service.MemberRecordService
|
||||
import com.ray650128.pcredive.database.service.MemberService
|
||||
import io.ktor.http.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import io.ktor.server.plugins.contentnegotiation.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.routing.*
|
||||
import io.ktor.server.util.*
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import org.litote.kmongo.toId
|
||||
import java.util.*
|
||||
|
||||
fun Application.configureMemberRecordRouting() {
|
||||
routing {
|
||||
get("/json/kotlinx-serialization") {
|
||||
call.respond(mapOf("hello" to "world"))
|
||||
route("/api") {
|
||||
route("/record") {
|
||||
get {
|
||||
val calendar = Calendar.getInstance().apply {
|
||||
timeInMillis = System.currentTimeMillis() - (5 * 60 * 60 * 1000) // 由於公連換日為每日早上5:00,因此減去時差
|
||||
}
|
||||
val records = getData(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH))
|
||||
call.respond(HttpStatusCode.OK, records)
|
||||
}
|
||||
post("/{id}") {
|
||||
val id = call.parameters.getOrFail<String>("id")
|
||||
val record = call.receive<MemberRecord>()
|
||||
val member = MemberService.findById(id) ?: run {
|
||||
call.respond(HttpStatusCode.NotFound)
|
||||
return@post
|
||||
}
|
||||
record.apply {
|
||||
memberId = member._id
|
||||
createdAt = System.currentTimeMillis()
|
||||
updatedAt = System.currentTimeMillis()
|
||||
}
|
||||
MemberRecordService.create(record).let {
|
||||
call.respond(HttpStatusCode.OK, record)
|
||||
}
|
||||
}
|
||||
get("/{year}/{month}/{day}") {
|
||||
val year = call.parameters.getOrFail<Int>("year").toInt()
|
||||
val month = call.parameters.getOrFail<Int>("month").toInt() - 1
|
||||
val day = call.parameters.getOrFail<Int>("day").toInt()
|
||||
val records = getData(year, month, day)
|
||||
call.respond(HttpStatusCode.OK, records)
|
||||
}
|
||||
get("/{id}") {
|
||||
// Show an article with a specific id
|
||||
val id = call.parameters.getOrFail<String>("id")
|
||||
val record = MemberRecordService.findById(id)?.toDto() ?: run {
|
||||
call.respond(HttpStatusCode.NotFound)
|
||||
return@get
|
||||
}
|
||||
call.respond(HttpStatusCode.OK, record)
|
||||
}
|
||||
put("/{id}") {
|
||||
val id = call.parameters.getOrFail<String>("id")
|
||||
val record = call.receive<UpdateMemberRecord>()
|
||||
val oldData = MemberRecordService.findById(id) ?: run {
|
||||
call.respond(HttpStatusCode.NotFound)
|
||||
return@put
|
||||
}
|
||||
oldData.apply {
|
||||
record1 = record.record1
|
||||
record1c = record.record1c
|
||||
record2 = record.record2
|
||||
record2c = record.record2c
|
||||
record3 = record.record3
|
||||
record3c = record.record3c
|
||||
createdAt = System.currentTimeMillis()
|
||||
updatedAt = System.currentTimeMillis()
|
||||
}
|
||||
MemberRecordService.updateById(id, oldData)
|
||||
call.respond(HttpStatusCode.OK, record)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getData(year: Int, month: Int, day: Int): List<RecordData> {
|
||||
val calendar = Calendar.getInstance().apply {
|
||||
set(Calendar.YEAR, year)
|
||||
set(Calendar.MONTH, month)
|
||||
set(Calendar.DAY_OF_MONTH, day)
|
||||
}
|
||||
val startTime = calendar.apply {
|
||||
set(Calendar.HOUR_OF_DAY, 5)
|
||||
set(Calendar.MINUTE, 0)
|
||||
set(Calendar.SECOND, 0)
|
||||
set(Calendar.MILLISECOND, 0)
|
||||
}.timeInMillis
|
||||
val endTime = startTime + 86399000L
|
||||
// Show a list of articles
|
||||
val records = ArrayList<RecordData>()
|
||||
val memberList = MemberService.findAll()
|
||||
memberList.forEach { member ->
|
||||
records.add(
|
||||
RecordData(member = member, MemberRecord())
|
||||
)
|
||||
}
|
||||
val recordList = MemberRecordService.findByTimeBetween(startTime, endTime)
|
||||
recordList.forEach { record ->
|
||||
val player = MemberService.findById(record.memberId.toString())
|
||||
records.firstOrNull { it.member == player }?.let { playerRecord ->
|
||||
playerRecord.record = record
|
||||
}
|
||||
}
|
||||
return records
|
||||
}
|
||||
|
||||
@ -1,15 +1,80 @@
|
||||
package com.ray650128.pcredive.plugins
|
||||
|
||||
import com.ray650128.pcredive.database.dto.toDto
|
||||
import com.ray650128.pcredive.database.model.Member
|
||||
import com.ray650128.pcredive.database.service.MemberService
|
||||
import io.ktor.http.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import io.ktor.server.plugins.contentnegotiation.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.routing.*
|
||||
import io.ktor.server.util.*
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
|
||||
fun Application.configureMemberRouting() {
|
||||
routing {
|
||||
get("/json/kotlinx-serialization") {
|
||||
call.respond(mapOf("hello" to "world"))
|
||||
route("/api") {
|
||||
route("/member") {
|
||||
get("/all") {
|
||||
// 顯示所有登錄的成員資料
|
||||
coroutineScope {
|
||||
val memberList = MemberService.findAll()
|
||||
call.respond(HttpStatusCode.OK, memberList)
|
||||
}
|
||||
}
|
||||
get("/{id}") {
|
||||
val id = call.parameters.getOrFail<String>("id")
|
||||
val member = MemberService.findById(id) ?: run {
|
||||
call.respond(HttpStatusCode.NotFound)
|
||||
return@get
|
||||
}
|
||||
call.respond(HttpStatusCode.OK, member)
|
||||
}
|
||||
post("/new") {
|
||||
// Save an article
|
||||
val formParameters = call.receiveParameters()
|
||||
val _playerName = formParameters.getOrFail("playerName")
|
||||
val _nickName = formParameters.getOrFail("nickName")
|
||||
val _discordID = formParameters.getOrFail("discordID")
|
||||
val _uid = formParameters.getOrFail("uid")
|
||||
val _createAt = System.currentTimeMillis()
|
||||
val member = Member(
|
||||
playerName = _playerName,
|
||||
nickName = _nickName,
|
||||
discordID = _discordID,
|
||||
uid = _uid,
|
||||
createAt = _createAt,
|
||||
)
|
||||
MemberService.create(member).let { memberId ->
|
||||
|
||||
call.respond(HttpStatusCode.OK, member)
|
||||
}
|
||||
}
|
||||
put("/{id}") {
|
||||
val id = call.parameters.getOrFail<String>("id")
|
||||
val formParameters = call.receiveParameters()
|
||||
coroutineScope {
|
||||
val _playerName = formParameters.getOrFail("playerName")
|
||||
val _nickName = formParameters.getOrFail("nickName")
|
||||
val _discordID = formParameters.getOrFail("discordID")
|
||||
val _uid = formParameters.getOrFail("uid")
|
||||
val _leave = (formParameters.getOrFail("leave") == "2")
|
||||
val _updatedAt = System.currentTimeMillis()
|
||||
val member = Member(
|
||||
playerName = _playerName,
|
||||
nickName = _nickName,
|
||||
discordID = _discordID,
|
||||
uid = _uid,
|
||||
leave = _leave,
|
||||
updatedAt = _updatedAt,
|
||||
)
|
||||
MemberService.updateById(id, member)
|
||||
call.respondRedirect("/memberList/$id")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,9 +5,13 @@ import io.ktor.server.plugins.contentnegotiation.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.routing.*
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.litote.kmongo.id.serialization.IdKotlinXSerializationModule
|
||||
|
||||
fun Application.configureSerialization() {
|
||||
install(ContentNegotiation) {
|
||||
json()
|
||||
json(
|
||||
Json { serializersModule = IdKotlinXSerializationModule }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
ktor {
|
||||
deployment {
|
||||
port = 8080
|
||||
port = 10001
|
||||
port = ${?PORT}
|
||||
}
|
||||
application {
|
||||
|
||||
@ -11,7 +11,10 @@ class ApplicationTest {
|
||||
@Test
|
||||
fun testRoot() = testApplication {
|
||||
application {
|
||||
configureRouting()
|
||||
configureHTTP()
|
||||
configureSerialization()
|
||||
configureMemberRouting()
|
||||
configureMemberRecordRouting()
|
||||
}
|
||||
client.get("/").apply {
|
||||
assertEquals(HttpStatusCode.OK, status)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user