feat🔫: change api

This commit is contained in:
车厘子 2022-11-17 17:35:51 +08:00
parent 4f1c9b2192
commit b5ca96d6b0
13 changed files with 129 additions and 136 deletions

View File

@ -12,7 +12,6 @@ plugins {
} }
group = "cn.fadinglight" group = "cn.fadinglight"
version = "0.0.1" version = "0.0.1"
application { application {
@ -22,7 +21,6 @@ application {
applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment") applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment")
} }
tasks.withType<Jar> { tasks.withType<Jar> {
manifest { manifest {
attributes( attributes(

View File

@ -1,36 +0,0 @@
package cn.fadinglight.dao
import cn.fadinglight.models.Bill
import cn.fadinglight.models.BillType
import kotlinx.serialization.Serializable
@Serializable
data class BillDao(
val id: Int? = null,
val type: String,
val date: String,
val money: Int,
val cls: String,
val label: String,
val options: String? = null,
)
fun BillDao.bill() = Bill(
id = id,
type = BillType.valueOf(type),
date = date,
money = money,
cls = cls,
label = label,
options = options ?: "",
)
fun Bill.dao() = BillDao(
id = id,
type = type.name,
date = date,
money = money,
cls = cls,
label = label,
options = options,
)

View File

@ -1,25 +0,0 @@
package cn.fadinglight.dao
import cn.fadinglight.models.Label
import cn.fadinglight.models.LabelType
data class LabelDao(
val name: String,
val count: Int,
var labels: List<LabelDao>?,
)
fun LabelDao.label(type: LabelType) = Label(
id = null,
type = type,
name = name,
count = 0,
relativedId = null
)
fun Label.dao() = LabelDao(
name = name,
count = count,
labels = emptyList(),
)

View File

@ -8,11 +8,11 @@ data class RespData<T>(val code: Int, val data: T?, val message: String?)
sealed class Resp<T> { sealed class Resp<T> {
abstract fun json(): RespData<T> abstract fun json(): RespData<T>
class Ok<T>(val data: T) : Resp<T>() { class Ok<T>(private val data: T) : Resp<T>() {
override fun json() = RespData<T>(code = 0, data = data, message = null) override fun json() = RespData(code = 0, data = data, message = null)
} }
class Error(val message: String?, val code: Int) : Resp<Unit>() { class Error(private val message: String?, val code: Int) : Resp<Unit>() {
override fun json(): RespData<Unit> = RespData(code = code, data = null, message = message) override fun json(): RespData<Unit> = RespData(code = code, data = null, message = message)
} }

View File

@ -12,8 +12,8 @@ data class Bill(
var id: Int?, var id: Int?,
val type: BillType, val type: BillType,
val date: String, val date: String,
val money: Int, val money: Float,
val cls: String, val cls: String,
val label: String, val label: String,
val options: String?, val options: String = "",
) )

View File

@ -4,6 +4,7 @@ package cn.fadinglight.models
enum class LabelType { enum class LabelType {
CLASS, CLASS,
LABEL, LABEL,
INCOME_CLASS,
} }
data class Label( data class Label(

View File

@ -10,7 +10,7 @@ fun Application.configureRouting() {
routing { routing {
route("/") { route("/") {
get { get {
call.respondText("Hello World!") call.respondText("Welcome che's Bill App!")
} }
} }
route("/api/v1") { route("/api/v1") {

View File

@ -1,45 +1,54 @@
package cn.fadinglight.routes package cn.fadinglight.routes
import cn.fadinglight.dao.BillDao
import cn.fadinglight.dao.bill
import cn.fadinglight.libs.Resp import cn.fadinglight.libs.Resp
import cn.fadinglight.services.BillServiceImpl import cn.fadinglight.services.BillServiceImpl
import cn.fadinglight.vo.BillVO
import cn.fadinglight.vo.bill
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.request.* import io.ktor.server.request.*
import io.ktor.server.response.* import io.ktor.server.response.*
import io.ktor.server.routing.* import io.ktor.server.routing.*
import java.lang.Exception import io.ktor.server.util.*
fun Route.billRoute() { fun Route.billRoute() {
val billService = BillServiceImpl() val billService = BillServiceImpl()
route("/bill") { route("/bill") {
get("/{year}/{month}") { get("/{year}/{month}") {
val year = call.parameters["year"]!! runCatching {
val month = call.parameters["month"]!! val year = call.parameters["year"]!!
call.respond(Resp.Ok(billService.getManyBills(year, month)).json()) val month = call.parameters["month"]!!
billService.getManyBills(year, month)
}.onSuccess {
call.respond(Resp.Ok(it).json())
}.onFailure {
call.respond(Resp.Error(it.message, code = -1).json())
}
} }
get { get("/") {
call.respond(status = HttpStatusCode.OK, Resp.Ok(billService.getManyBills()).json()) call.respond(status = HttpStatusCode.OK, Resp.Ok(billService.getManyBills()).json())
} }
post { post("/") {
try { runCatching {
val bills = call.receive<List<BillDao>>().map(BillDao::bill) val bills = call.receive<List<BillVO>>().map(BillVO::bill)
val count = billService.addManyBills(bills) billService.addManyBills(bills)
call.respond(status = HttpStatusCode.Created, Resp.Ok(count).json()) }.onSuccess {
} catch (e: Exception) { call.respond(Resp.Ok(it).json())
call.respond(status = HttpStatusCode.Created, Resp.Error(e.message, code = -1).json()) }.onFailure {
call.respond(Resp.Error(it.message, code = -1).json())
} }
} }
delete("{id}") { delete("{id}") {
val id = call.parameters["id"]!!.toInt() val id = call.parameters.getOrFail("id").toInt()
val count = billService.deleteOneBill(id) val count = billService.deleteOneBill(id)
call.respond(status = HttpStatusCode.OK, Resp.Ok(count).json()) call.respond(status = HttpStatusCode.OK, Resp.Ok(count).json())
} }
put {
val bill = call.receive<BillDao>().bill() put("/") {
val bill = call.receive<BillVO>().bill()
val count = billService.updateOneBill(bill) val count = billService.updateOneBill(bill)
call.respond(status = HttpStatusCode.OK, Resp.Ok(count).json()) call.respond(status = HttpStatusCode.OK, Resp.Ok(count).json())
} }

View File

@ -1,10 +1,23 @@
package cn.fadinglight.routes package cn.fadinglight.routes
import cn.fadinglight.libs.Resp
import cn.fadinglight.services.LabelServiceImpl
import cn.fadinglight.vo.LabelVO
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.* import io.ktor.server.routing.*
fun Route.labelRoute() { fun Route.labelRoute() {
val labelService = LabelServiceImpl()
route("/label") { route("/label") {
get {} get("/") {
call.respond(
Resp.Ok(
// mapOf("consume" to listOf<LabelVO>(), "income" to listOf<LabelVO>())
labelService.getLabels()
).json()
)
}
post {} post {}
} }
} }

View File

@ -6,7 +6,7 @@ interface BillService {
suspend fun getManyBills(year: String, month: String): List<Bill> suspend fun getManyBills(year: String, month: String): List<Bill>
suspend fun getManyBills(year: String, month: String, day: String): List<Bill> suspend fun getManyBills(year: String, month: String, day: String): List<Bill>
suspend fun getManyBills(): List<Bill> suspend fun getManyBills(): List<Bill>
suspend fun getOneBill(billId: Int): Bill suspend fun getOneBill(billId: Int): Bill?
suspend fun addManyBills(bills: List<Bill>): Int suspend fun addManyBills(bills: List<Bill>): Int
suspend fun addOneBill(bill: Bill): Int suspend fun addOneBill(bill: Bill): Int
suspend fun updateManyBills(bills: List<Bill>): Int suspend fun updateManyBills(bills: List<Bill>): Int

View File

@ -1,6 +1,7 @@
package cn.fadinglight.services package cn.fadinglight.services
import cn.fadinglight.mapers.Bills import cn.fadinglight.mapers.Bills
import cn.fadinglight.mapers.Labels
import cn.fadinglight.models.Bill import cn.fadinglight.models.Bill
import cn.fadinglight.models.BillType import cn.fadinglight.models.BillType
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.*
@ -21,43 +22,61 @@ class BillServiceImpl : BillService {
) )
override suspend fun getManyBills(year: String, month: String): List<Bill> = transaction { override suspend fun getManyBills(year: String, month: String): List<Bill> = transaction {
Bills.select(Bills.date like "%${year}-${month}%").map(::resultRowToBill) Bills
.select(Bills.date like "%${year}-${month}%")
.map(::resultRowToBill)
} }
override suspend fun getManyBills(year: String, month: String, day: String): List<Bill> = transaction { override suspend fun getManyBills(year: String, month: String, day: String): List<Bill> = transaction {
Bills.select(Bills.date eq "${year}-${month}-${day}").map(::resultRowToBill) Bills
.select(Bills.date eq "${year}-${month}-${day}")
.map(::resultRowToBill)
} }
override suspend fun getManyBills(): List<Bill> = transaction { override suspend fun getManyBills(): List<Bill> = transaction {
Bills.selectAll().map(::resultRowToBill) Bills
.selectAll()
.map(::resultRowToBill)
} }
override suspend fun getOneBill(billId: Int): Bill = transaction { override suspend fun getOneBill(billId: Int): Bill? = transaction {
Bills.select(Bills.id eq billId).single().let(::resultRowToBill) Bills
.select(Bills.id eq billId)
.map(::resultRowToBill)
.singleOrNull()
} }
override suspend fun addOneBill(bill: Bill): Int = transaction { override suspend fun addOneBill(bill: Bill): Int = transaction {
Bills.insertAndGetId { Bills
it[type] = bill.type.name .insertAndGetId {
it[date] = bill.date it[type] = bill.type.name
it[cls] = bill.cls it[date] = bill.date
it[label] = bill.label it[cls] = bill.cls
it[money] = bill.money it[label] = bill.label
it[options] = bill.options it[money] = bill.money
}.value it[options] = bill.options
}
Labels
.update({ Labels.name inList listOf(bill.cls, bill.label) }) {
with(SqlExpressionBuilder) {
it[count] = count + 1
}
}
} }
override suspend fun addManyBills(bills: List<Bill>): Int = transaction { override suspend fun addManyBills(bills: List<Bill>): Int = transaction {
Bills.batchInsert(bills) { Bills
this[Bills.type] = it.type.name .batchInsert(bills) {
this[Bills.date] = it.date this[Bills.type] = it.type.name
this[Bills.cls] = it.cls this[Bills.date] = it.date
this[Bills.label] = it.label this[Bills.cls] = it.cls
this[Bills.money] = it.money this[Bills.label] = it.label
this[Bills.options] = it.options this[Bills.money] = it.money
}.count() this[Bills.options] = it.options
}
.count()
} }
override suspend fun updateManyBills(bills: List<Bill>): Int { override suspend fun updateManyBills(bills: List<Bill>): Int {
@ -65,14 +84,15 @@ class BillServiceImpl : BillService {
} }
override suspend fun updateOneBill(bill: Bill) = transaction { override suspend fun updateOneBill(bill: Bill) = transaction {
Bills.update({ Bills.id eq bill.id }) { Bills
it[type] = bill.type.name .update({ Bills.id eq bill.id }) {
it[date] = bill.date it[type] = bill.type.name
it[money] = bill.money it[date] = bill.date
it[cls] = bill.cls it[money] = bill.money
it[label] = bill.label it[cls] = bill.cls
it[options] = bill.options it[label] = bill.label
} it[options] = bill.options
}
} }
override suspend fun deleteManyBills(bills: List<Bill>): Int { override suspend fun deleteManyBills(bills: List<Bill>): Int {
@ -80,8 +100,7 @@ class BillServiceImpl : BillService {
} }
override suspend fun deleteOneBill(billId: Int): Int = transaction { override suspend fun deleteOneBill(billId: Int): Int = transaction {
Bills.deleteWhere { Bills.id eq billId } Bills
.deleteWhere { Bills.id eq billId }
} }
} }

View File

@ -1,11 +1,11 @@
package cn.fadinglight.services package cn.fadinglight.services
import cn.fadinglight.dao.LabelDao
import cn.fadinglight.models.Label import cn.fadinglight.models.Label
import cn.fadinglight.models.LabelType import cn.fadinglight.models.LabelType
import cn.fadinglight.vo.LabelGroup
interface LabelService { interface LabelService {
suspend fun getLabels(): List<LabelDao> suspend fun getLabels(): LabelGroup
suspend fun addLabel(labelType: LabelType, label: Label): Int suspend fun addLabel(labelType: LabelType, label: Label): Int
suspend fun deleteLabel(labelId: Int): Int suspend fun deleteLabel(labelId: Int): Int
suspend fun addCount(labelId: Int): Int suspend fun addCount(labelId: Int): Int

View File

@ -1,10 +1,11 @@
package cn.fadinglight.services package cn.fadinglight.services
import cn.fadinglight.dao.LabelDao import cn.fadinglight.vo.LabelVO
import cn.fadinglight.dao.dao import cn.fadinglight.vo.vo
import cn.fadinglight.mapers.Labels import cn.fadinglight.mapers.Labels
import cn.fadinglight.models.Label import cn.fadinglight.models.Label
import cn.fadinglight.models.LabelType import cn.fadinglight.models.LabelType
import cn.fadinglight.vo.LabelGroup
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.transactions.transaction
@ -17,18 +18,32 @@ class LabelServiceImpl : LabelService {
relativedId = row[Labels.relativeId] relativedId = row[Labels.relativeId]
) )
override suspend fun getLabels(): List<LabelDao> { override suspend fun getLabels(): LabelGroup {
val labelGroups = transaction { val labelGroups = transaction {
Labels.selectAll().map(::resultRowToLabel).groupBy { it.type } Labels
.selectAll()
.map(::resultRowToLabel)
.groupBy { it.type }
} }
return labelGroups[LabelType.CLASS]?.map { val consumeLabels = labelGroups[LabelType.CLASS]
it.dao().apply { ?.map {
labels = labelGroups[LabelType.LABEL] it.vo().apply {
?.filter { it2 -> it2.relativedId == it.id } this.labels = labelGroups[LabelType.LABEL]
?.map(Label::dao) ?.filter { it2 -> it2.relativedId == it.id }
?: emptyList() ?.map(Label::vo)
} ?: emptyList()
} ?: emptyList() }
} ?: emptyList()
val incomeLabels = labelGroups[LabelType.CLASS]
?.map {
it.vo().apply {
this.labels = labelGroups[LabelType.INCOME_CLASS]
?.filter { it2 -> it2.relativedId == it.id }
?.map(Label::vo)
?: emptyList()
}
} ?: emptyList()
return LabelGroup(income = incomeLabels, consume = consumeLabels)
} }
override suspend fun addLabel(labelType: LabelType, label: Label): Int = transaction { override suspend fun addLabel(labelType: LabelType, label: Label): Int = transaction {
@ -51,5 +66,4 @@ class LabelServiceImpl : LabelService {
} }
} }
} }
} }