Compare commits
No commits in common. "5857abbe05375537a37e9df619de3bb8a7045f51" and "0068f71977e03bbb0f77769535aab40ada9e69e1" have entirely different histories.
5857abbe05
...
0068f71977
51
README.md
51
README.md
|
@ -1,48 +1,11 @@
|
||||||
# Ktor 项目
|
# Ktor 项目模板
|
||||||
|
|
||||||
> Kotlin + Gradle + Ktor + Exposed + Docker
|
> Kotlin + Gradle + Ktor + Exposed + Docker
|
||||||
|
|
||||||
## api
|
配置好啦
|
||||||
|
|
||||||
### bill
|
- Database
|
||||||
|
- Logging
|
||||||
```bash
|
- Routing
|
||||||
GET /api/v1/bill/{year}/{month?}/{day?}
|
- Session
|
||||||
|
- WebSocket
|
||||||
POST /api/v1/bill/
|
|
||||||
Body List<{
|
|
||||||
type: Int,
|
|
||||||
date: String,
|
|
||||||
money: Float,
|
|
||||||
cls: String,
|
|
||||||
label: String,
|
|
||||||
options: String,
|
|
||||||
}>
|
|
||||||
|
|
||||||
DELETE /api/v1/bill/{id}
|
|
||||||
|
|
||||||
PUT /api/v1/bill/
|
|
||||||
Body {
|
|
||||||
id: Int?,
|
|
||||||
type: Int,
|
|
||||||
date: String,
|
|
||||||
money: Float,
|
|
||||||
cls: String,
|
|
||||||
label: String,
|
|
||||||
options: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### label
|
|
||||||
|
|
||||||
```bash
|
|
||||||
GET /api/v1/label/
|
|
||||||
|
|
||||||
POST /api/v1/label/
|
|
||||||
Body {
|
|
||||||
type: String,
|
|
||||||
name: String,
|
|
||||||
relativeId: Int?,
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -13,7 +13,7 @@ plugins {
|
||||||
|
|
||||||
|
|
||||||
group = "cn.fadinglight"
|
group = "cn.fadinglight"
|
||||||
version = "1.0.1"
|
version = "0.0.1"
|
||||||
application {
|
application {
|
||||||
mainClass.set("cn.fadinglight.ApplicationKt")
|
mainClass.set("cn.fadinglight.ApplicationKt")
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,4 @@
|
||||||
services:
|
services:
|
||||||
# back:
|
|
||||||
# container_name: bill-ktor
|
|
||||||
# image: registry.cn-hangzhou.aliyuncs.com/fadinglight/bill-ktor:dev
|
|
||||||
# restart: always
|
|
||||||
# environment:
|
|
||||||
# JDBC_URL: mariadb://db/bill
|
|
||||||
# ports:
|
|
||||||
# - 80:4000
|
|
||||||
|
|
||||||
db:
|
db:
|
||||||
container_name: bill-test-db
|
container_name: bill-test-db
|
||||||
image: mariadb
|
image: mariadb
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
import aiohttp
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
mongo_url = 'http://www.fadinglight.cn:8088/list'
|
|
||||||
mysql_url = 'http://localhost:8080/api/v1/bill/'
|
|
||||||
|
|
||||||
|
|
||||||
async def getMongoBills():
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
async with session.get(mongo_url) as response:
|
|
||||||
data = await response.json()
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
async def postBillsToMysql(bills):
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
async with session.post(mysql_url, json=bills) as response:
|
|
||||||
data = await response.json()
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def dealOneBill(bill):
|
|
||||||
bill.setdefault('type', 0)
|
|
||||||
return dict(
|
|
||||||
money=bill['money'],
|
|
||||||
cls=bill['cls'],
|
|
||||||
label=bill['label'],
|
|
||||||
date=bill['date'],
|
|
||||||
options=bill['options'],
|
|
||||||
type="consume" if bill['type'] == 0 else "income",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def transType(bill):
|
|
||||||
bill['type'] = 0 if bill['type'].lower() == 'income' else 1
|
|
||||||
return bill
|
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
|
||||||
data = await getMongoBills()
|
|
||||||
bills = data['data']
|
|
||||||
bills = list(map(dealOneBill, bills))
|
|
||||||
bills = list(map(transType, bills))
|
|
||||||
respData = await postBillsToMysql(bills)
|
|
||||||
print(respData)
|
|
||||||
|
|
||||||
|
|
||||||
asyncio.run(main())
|
|
|
@ -1,54 +0,0 @@
|
||||||
import aiohttp
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
mongo_url = 'http://www.fadinglight.cn:8088/class'
|
|
||||||
mysql_url = 'http://localhost:8080/api/v1/label/'
|
|
||||||
|
|
||||||
|
|
||||||
async def getMongoLabels():
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
async with session.get(mongo_url) as response:
|
|
||||||
data = await response.json()
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
async def postLabelsToMysql(label):
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
async with session.post(mysql_url, json=label) as response:
|
|
||||||
data = await response.json()
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def newLabel(name, type=0, relativeId=None):
|
|
||||||
return dict(
|
|
||||||
name=name,
|
|
||||||
type=type,
|
|
||||||
relativeId=relativeId,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
|
||||||
data = await getMongoLabels()
|
|
||||||
labels = data['data']
|
|
||||||
consumeLabels = labels['consume']
|
|
||||||
incomeLabels = labels['income']
|
|
||||||
|
|
||||||
print(consumeLabels)
|
|
||||||
|
|
||||||
for i in incomeLabels:
|
|
||||||
label = newLabel(i, type=2)
|
|
||||||
# print(label)
|
|
||||||
await postLabelsToMysql(label)
|
|
||||||
|
|
||||||
for i in consumeLabels:
|
|
||||||
subLabels = consumeLabels[i]
|
|
||||||
label = newLabel(i, type=0)
|
|
||||||
resp = await postLabelsToMysql(label)
|
|
||||||
id = resp['data']
|
|
||||||
print(id)
|
|
||||||
for j in subLabels:
|
|
||||||
sub_label = newLabel(j, type=1, relativeId=id)
|
|
||||||
await postLabelsToMysql(sub_label)
|
|
||||||
|
|
||||||
|
|
||||||
asyncio.run(main())
|
|
|
@ -9,10 +9,10 @@ sealed class Resp<T> {
|
||||||
abstract fun json(): RespData<T>
|
abstract fun json(): RespData<T>
|
||||||
|
|
||||||
class Ok<T>(private val data: T) : Resp<T>() {
|
class Ok<T>(private val data: T) : Resp<T>() {
|
||||||
override fun json() = RespData(code = 0, data = data, message = "")
|
override fun json() = RespData(code = 0, data = data, message = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Error(private val message: String? = "", val code: Int = -1) : 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,9 @@ import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
|
||||||
enum class BillType {
|
enum class BillType {
|
||||||
CONSUME,
|
Consume,
|
||||||
INCOME;
|
Income,
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun of(n: Int): BillType = when (n) {
|
|
||||||
0 -> CONSUME
|
|
||||||
1 -> INCOME
|
|
||||||
else -> throw IllegalArgumentException("error code $n")
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Bill(
|
data class Bill(
|
||||||
var id: Int?,
|
var id: Int?,
|
||||||
|
|
|
@ -2,19 +2,9 @@ package cn.fadinglight.models
|
||||||
|
|
||||||
|
|
||||||
enum class LabelType {
|
enum class LabelType {
|
||||||
CONSUME_CLASS,
|
CLASS,
|
||||||
CONSUME_LABEL,
|
LABEL,
|
||||||
INCOME_CLASS;
|
INCOME_CLASS,
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun of(n: Int) = when (n) {
|
|
||||||
0 -> CONSUME_CLASS
|
|
||||||
1 -> CONSUME_LABEL
|
|
||||||
2 -> INCOME_CLASS
|
|
||||||
else -> throw IllegalArgumentException("error code $n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Label(
|
data class Label(
|
||||||
|
@ -22,5 +12,5 @@ data class Label(
|
||||||
val type: LabelType,
|
val type: LabelType,
|
||||||
val name: String,
|
val name: String,
|
||||||
var count: Int,
|
var count: Int,
|
||||||
val relativeId: Int?,
|
val relativedId: Int?,
|
||||||
)
|
)
|
|
@ -14,10 +14,6 @@ const val HIKARI_CONFIG_KEY = "ktor.hikariConfig"
|
||||||
fun Application.configureDatabase() {
|
fun Application.configureDatabase() {
|
||||||
val configPath = environment.config.property(HIKARI_CONFIG_KEY).getString()
|
val configPath = environment.config.property(HIKARI_CONFIG_KEY).getString()
|
||||||
val dbConfig = HikariConfig(configPath)
|
val dbConfig = HikariConfig(configPath)
|
||||||
val envs = System.getenv()
|
|
||||||
if (envs.containsKey("JDBC_URL")) {
|
|
||||||
dbConfig.jdbcUrl = envs["JDBC_URL"]
|
|
||||||
}
|
|
||||||
val dataSource = HikariDataSource(dbConfig)
|
val dataSource = HikariDataSource(dbConfig)
|
||||||
Database.connect(dataSource)
|
Database.connect(dataSource)
|
||||||
createTables()
|
createTables()
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package cn.fadinglight.plugins
|
package cn.fadinglight.plugins
|
||||||
|
|
||||||
import cn.fadinglight.models.LabelType
|
|
||||||
import cn.fadinglight.routes.billRoute
|
import cn.fadinglight.routes.billRoute
|
||||||
import cn.fadinglight.routes.labelRoute
|
import cn.fadinglight.routes.labelRoute
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
|
@ -11,7 +10,7 @@ fun Application.configureRouting() {
|
||||||
routing {
|
routing {
|
||||||
route("/") {
|
route("/") {
|
||||||
get {
|
get {
|
||||||
call.respond("Hello world")
|
call.respondText("Welcome che's Bill App!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
route("/api/v1") {
|
route("/api/v1") {
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package cn.fadinglight.routes
|
package cn.fadinglight.routes
|
||||||
|
|
||||||
import cn.fadinglight.libs.Resp
|
import cn.fadinglight.libs.Resp
|
||||||
import cn.fadinglight.models.Bill
|
|
||||||
import cn.fadinglight.services.BillServiceImpl
|
import cn.fadinglight.services.BillServiceImpl
|
||||||
import cn.fadinglight.vo.BillVO
|
import cn.fadinglight.vo.BillVO
|
||||||
import cn.fadinglight.vo.bill
|
import cn.fadinglight.vo.bill
|
||||||
import cn.fadinglight.vo.vo
|
|
||||||
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.*
|
||||||
|
@ -16,25 +14,22 @@ import io.ktor.server.util.*
|
||||||
fun Route.billRoute() {
|
fun Route.billRoute() {
|
||||||
val billService = BillServiceImpl()
|
val billService = BillServiceImpl()
|
||||||
route("/bill") {
|
route("/bill") {
|
||||||
get("/{year}/{month?}/{day?}") {
|
get("/{year}/{month}") {
|
||||||
runCatching {
|
runCatching {
|
||||||
val year = call.parameters.getOrFail("year")
|
val year = call.parameters["year"]!!
|
||||||
val month = call.parameters["month"]
|
val month = call.parameters["month"]!!
|
||||||
val day = call.parameters["day"]
|
billService.getManyBills(year, month)
|
||||||
if (month is String && day is String) {
|
|
||||||
billService.getManyBills(year, month, day).map(Bill::vo)
|
|
||||||
} else if (month is String) {
|
|
||||||
billService.getManyBills(year, month).map(Bill::vo)
|
|
||||||
} else {
|
|
||||||
billService.getManyBills(year).map(Bill::vo)
|
|
||||||
}
|
|
||||||
}.onSuccess {
|
}.onSuccess {
|
||||||
call.respond(Resp.Ok(it).json())
|
call.respond(Resp.Ok(it).json())
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
call.respond(Resp.Error(it.message).json())
|
call.respond(Resp.Error(it.message, code = -1).json())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get("/") {
|
||||||
|
call.respond(status = HttpStatusCode.OK, Resp.Ok(billService.getManyBills()).json())
|
||||||
|
}
|
||||||
|
|
||||||
post("/") {
|
post("/") {
|
||||||
runCatching {
|
runCatching {
|
||||||
val bills = call.receive<List<BillVO>>().map(BillVO::bill)
|
val bills = call.receive<List<BillVO>>().map(BillVO::bill)
|
||||||
|
@ -47,25 +42,15 @@ fun Route.billRoute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
delete("{id}") {
|
delete("{id}") {
|
||||||
runCatching {
|
|
||||||
val id = call.parameters.getOrFail("id").toInt()
|
val id = call.parameters.getOrFail("id").toInt()
|
||||||
billService.deleteOneBill(id)
|
val count = billService.deleteOneBill(id)
|
||||||
}.onSuccess {
|
call.respond(status = HttpStatusCode.OK, Resp.Ok(count).json())
|
||||||
call.respond(status = HttpStatusCode.OK, Resp.Ok(it).json())
|
|
||||||
}.onFailure {
|
|
||||||
call.respond(Resp.Error(it.message).json())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
put("/") {
|
put("/") {
|
||||||
runCatching {
|
|
||||||
val bill = call.receive<BillVO>().bill()
|
val bill = call.receive<BillVO>().bill()
|
||||||
billService.updateOneBill(bill)
|
val count = billService.updateOneBill(bill)
|
||||||
}.onSuccess {
|
call.respond(status = HttpStatusCode.OK, Resp.Ok(count).json())
|
||||||
call.respond(status = HttpStatusCode.OK, Resp.Ok(it).json())
|
|
||||||
}.onFailure {
|
|
||||||
call.respond(Resp.Error(it.message).json())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,10 +2,8 @@ package cn.fadinglight.routes
|
||||||
|
|
||||||
import cn.fadinglight.libs.Resp
|
import cn.fadinglight.libs.Resp
|
||||||
import cn.fadinglight.services.LabelServiceImpl
|
import cn.fadinglight.services.LabelServiceImpl
|
||||||
import cn.fadinglight.vo.LabelPost
|
import cn.fadinglight.vo.LabelVO
|
||||||
import cn.fadinglight.vo.label
|
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
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.*
|
||||||
|
|
||||||
|
@ -20,15 +18,6 @@ fun Route.labelRoute() {
|
||||||
).json()
|
).json()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
post("/") {
|
post {}
|
||||||
runCatching {
|
|
||||||
call.receive<LabelPost>().label()
|
|
||||||
}.onSuccess {
|
|
||||||
val labelId = labelService.addLabel(it)
|
|
||||||
call.respond(Resp.Ok(labelId).json())
|
|
||||||
}.onFailure {
|
|
||||||
call.respond(Resp.Error(it.message).json())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,6 @@ package cn.fadinglight.services
|
||||||
import cn.fadinglight.models.Bill
|
import cn.fadinglight.models.Bill
|
||||||
|
|
||||||
interface BillService {
|
interface BillService {
|
||||||
suspend fun getManyBills(year: String): List<Bill>
|
|
||||||
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>
|
||||||
|
|
|
@ -4,21 +4,13 @@ import cn.fadinglight.mapers.Bills
|
||||||
import cn.fadinglight.mapers.Labels
|
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 cn.fadinglight.models.LabelType
|
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList
|
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.like
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.like
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
|
||||||
|
|
||||||
class BillServiceImpl : BillService {
|
class BillServiceImpl : BillService {
|
||||||
private fun formatSingletonNumber(n: String) = if (n.length == 1) {
|
|
||||||
"0$n"
|
|
||||||
} else {
|
|
||||||
n
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun resultRowToBill(row: ResultRow) = Bill(
|
private fun resultRowToBill(row: ResultRow) = Bill(
|
||||||
id = row[Bills.id].value,
|
id = row[Bills.id].value,
|
||||||
type = BillType.valueOf(row[Bills.type]),
|
type = BillType.valueOf(row[Bills.type]),
|
||||||
|
@ -29,22 +21,16 @@ class BillServiceImpl : BillService {
|
||||||
options = row[Bills.options]
|
options = row[Bills.options]
|
||||||
)
|
)
|
||||||
|
|
||||||
override suspend fun getManyBills(year: String): List<Bill> = transaction {
|
|
||||||
Bills
|
|
||||||
.select(Bills.date like "${year}%")
|
|
||||||
.map(::resultRowToBill)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getManyBills(year: String, month: String): List<Bill> = transaction {
|
override suspend fun getManyBills(year: String, month: String): List<Bill> = transaction {
|
||||||
Bills
|
Bills
|
||||||
.select(Bills.date like "%${year}-${formatSingletonNumber(month)}%")
|
.select(Bills.date like "%${year}-${month}%")
|
||||||
.map(::resultRowToBill)
|
.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
|
Bills
|
||||||
.select(Bills.date eq "${year}-${formatSingletonNumber(month)}-${formatSingletonNumber(day)}")
|
.select(Bills.date eq "${year}-${month}-${day}")
|
||||||
.map(::resultRowToBill)
|
.map(::resultRowToBill)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +67,7 @@ class BillServiceImpl : BillService {
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun addManyBills(bills: List<Bill>): Int = transaction {
|
override suspend fun addManyBills(bills: List<Bill>): Int = transaction {
|
||||||
val newBills = Bills
|
Bills
|
||||||
.batchInsert(bills) {
|
.batchInsert(bills) {
|
||||||
this[Bills.type] = it.type.name
|
this[Bills.type] = it.type.name
|
||||||
this[Bills.date] = it.date
|
this[Bills.date] = it.date
|
||||||
|
@ -90,29 +76,7 @@ class BillServiceImpl : BillService {
|
||||||
this[Bills.money] = it.money
|
this[Bills.money] = it.money
|
||||||
this[Bills.options] = it.options
|
this[Bills.options] = it.options
|
||||||
}
|
}
|
||||||
.map(::resultRowToBill)
|
.count()
|
||||||
newBills.forEach {
|
|
||||||
val classId = Labels
|
|
||||||
.select(
|
|
||||||
(Labels.name eq it.cls) and (Labels.type inList listOf(
|
|
||||||
LabelType.CONSUME_CLASS,
|
|
||||||
LabelType.INCOME_CLASS
|
|
||||||
).map(LabelType::toString))
|
|
||||||
)
|
|
||||||
.map { it2 -> it2[Labels.id].value }
|
|
||||||
.singleOrNull()
|
|
||||||
val labelId = if (it.type == BillType.CONSUME) Labels
|
|
||||||
.select((Labels.name eq it.label) and (Labels.type eq LabelType.CONSUME_LABEL.toString()))
|
|
||||||
.map { it2 -> it2[Labels.id].value }
|
|
||||||
.singleOrNull()
|
|
||||||
else null
|
|
||||||
Labels.update({ (Labels.id eq labelId) or (Labels.id eq classId) }) {
|
|
||||||
with(SqlExpressionBuilder) {
|
|
||||||
it[count] = count + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newBills.count()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateManyBills(bills: List<Bill>): Int {
|
override suspend fun updateManyBills(bills: List<Bill>): Int {
|
||||||
|
|
|
@ -3,11 +3,10 @@ package cn.fadinglight.services
|
||||||
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 cn.fadinglight.vo.LabelGroup
|
||||||
import cn.fadinglight.vo.LabelPost
|
|
||||||
|
|
||||||
interface LabelService {
|
interface LabelService {
|
||||||
suspend fun getLabels(): LabelGroup
|
suspend fun getLabels(): LabelGroup
|
||||||
suspend fun addLabel(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
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package cn.fadinglight.services
|
package cn.fadinglight.services
|
||||||
|
|
||||||
|
import cn.fadinglight.vo.LabelVO
|
||||||
import cn.fadinglight.vo.vo
|
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
|
||||||
|
@ -14,7 +15,7 @@ class LabelServiceImpl : LabelService {
|
||||||
type = LabelType.valueOf(row[Labels.type]),
|
type = LabelType.valueOf(row[Labels.type]),
|
||||||
name = row[Labels.name],
|
name = row[Labels.name],
|
||||||
count = row[Labels.count],
|
count = row[Labels.count],
|
||||||
relativeId = row[Labels.relativeId]
|
relativedId = row[Labels.relativeId]
|
||||||
)
|
)
|
||||||
|
|
||||||
override suspend fun getLabels(): LabelGroup {
|
override suspend fun getLabels(): LabelGroup {
|
||||||
|
@ -24,32 +25,33 @@ class LabelServiceImpl : LabelService {
|
||||||
.map(::resultRowToLabel)
|
.map(::resultRowToLabel)
|
||||||
.groupBy { it.type }
|
.groupBy { it.type }
|
||||||
}
|
}
|
||||||
val consumeLabels = labelGroups[LabelType.CONSUME_CLASS]
|
val consumeLabels = labelGroups[LabelType.CLASS]
|
||||||
?.sortedByDescending { it.count }
|
|
||||||
?.map {
|
?.map {
|
||||||
it.vo().apply {
|
it.vo().apply {
|
||||||
this.labels = labelGroups[LabelType.CONSUME_LABEL]
|
this.labels = labelGroups[LabelType.LABEL]
|
||||||
?.filter { it2 -> it2.relativeId == it.id }
|
?.filter { it2 -> it2.relativedId == it.id }
|
||||||
?.sortedByDescending { it2 -> it2.count }
|
|
||||||
?.map { it2 -> it2.name }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?: emptyList()
|
|
||||||
val incomeLabels = labelGroups[LabelType.INCOME_CLASS]
|
|
||||||
?.sortedByDescending { it.count }
|
|
||||||
?.map(Label::vo)
|
?.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)
|
return LabelGroup(income = incomeLabels, consume = consumeLabels)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun addLabel(label: Label): Int = transaction {
|
override suspend fun addLabel(labelType: LabelType, label: Label): Int = transaction {
|
||||||
Labels
|
Labels.insertAndGetId {
|
||||||
.insertAndGetId {
|
|
||||||
it[type] = label.type.name
|
it[type] = label.type.name
|
||||||
it[name] = label.name
|
it[name] = label.name
|
||||||
it[count] = 0
|
it[count] = label.count
|
||||||
it[relativeId] = label.relativeId
|
it[relativeId] = label.relativedId
|
||||||
}.value
|
}.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,11 @@ package cn.fadinglight.vo
|
||||||
import cn.fadinglight.models.Bill
|
import cn.fadinglight.models.Bill
|
||||||
import cn.fadinglight.models.BillType
|
import cn.fadinglight.models.BillType
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class BillVO(
|
data class BillVO(
|
||||||
val id: Int? = null,
|
val id: Int? = null,
|
||||||
val type: Int,
|
val type: String,
|
||||||
val date: String,
|
val date: String,
|
||||||
val money: Float,
|
val money: Float,
|
||||||
val cls: String,
|
val cls: String,
|
||||||
|
@ -18,7 +17,7 @@ data class BillVO(
|
||||||
|
|
||||||
fun BillVO.bill() = Bill(
|
fun BillVO.bill() = Bill(
|
||||||
id = id,
|
id = id,
|
||||||
type = BillType.of(type),
|
type = BillType.valueOf(type),
|
||||||
date = date,
|
date = date,
|
||||||
money = money,
|
money = money,
|
||||||
cls = cls,
|
cls = cls,
|
||||||
|
@ -28,7 +27,7 @@ fun BillVO.bill() = Bill(
|
||||||
|
|
||||||
fun Bill.vo() = BillVO(
|
fun Bill.vo() = BillVO(
|
||||||
id = id,
|
id = id,
|
||||||
type = type.ordinal,
|
type = type.name,
|
||||||
date = date,
|
date = date,
|
||||||
money = money,
|
money = money,
|
||||||
cls = cls,
|
cls = cls,
|
||||||
|
|
|
@ -4,26 +4,11 @@ import cn.fadinglight.models.Label
|
||||||
import cn.fadinglight.models.LabelType
|
import cn.fadinglight.models.LabelType
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class LabelPost(
|
|
||||||
val type: Int,
|
|
||||||
val name: String,
|
|
||||||
val relativeId: Int?,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun LabelPost.label() = Label(
|
|
||||||
id = null,
|
|
||||||
type = LabelType.of(type),
|
|
||||||
name = name,
|
|
||||||
count = 0,
|
|
||||||
relativeId = relativeId
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class LabelVO(
|
data class LabelVO(
|
||||||
val name: String,
|
val name: String,
|
||||||
var labels: List<String>?,
|
val count: Int,
|
||||||
|
var labels: List<LabelVO>?,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
@ -33,7 +18,16 @@ data class LabelGroup(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
fun LabelVO.label(type: LabelType) = Label(
|
||||||
|
id = null,
|
||||||
|
type = type,
|
||||||
|
name = name,
|
||||||
|
count = 0,
|
||||||
|
relativedId = null
|
||||||
|
)
|
||||||
|
|
||||||
fun Label.vo() = LabelVO(
|
fun Label.vo() = LabelVO(
|
||||||
name = name,
|
name = name,
|
||||||
labels = null,
|
count = count,
|
||||||
|
labels = emptyList(),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user