From dc3acb18ce95cd118d401b5ea22d9000acd1b595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BD=A6=E5=8E=98=E5=AD=90?= Date: Sat, 26 Nov 2022 01:18:20 +0800 Subject: [PATCH] =?UTF-8?q?feat=F0=9F=94=AB:=20=E9=83=A8=E7=BD=B2=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yaml | 9 +++++ scripts/bills_mongo2mysql.py | 13 ++++++- scripts/labels_mongo2mysql.py | 39 +++++++++++-------- .../kotlin/cn/fadinglight/libs/Response.kt | 4 +- .../kotlin/cn/fadinglight/models/Label.kt | 10 ++--- .../kotlin/cn/fadinglight/plugins/Database.kt | 4 ++ .../kotlin/cn/fadinglight/plugins/Routing.kt | 2 +- .../cn/fadinglight/routes/BillRoutes.kt | 1 + .../fadinglight/services/BillServiceImpl.kt | 20 +++++++--- .../fadinglight/services/LabelServiceImpl.kt | 16 +++++--- src/main/kotlin/cn/fadinglight/vo/LabelVO.kt | 6 +-- src/main/resources/application.conf | 2 +- src/main/resources/db.properties | 2 +- 13 files changed, 85 insertions(+), 43 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 5ad57c0..511ccf2 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,4 +1,13 @@ 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: container_name: bill-test-db image: mariadb diff --git a/scripts/bills_mongo2mysql.py b/scripts/bills_mongo2mysql.py index 1f63760..68555b8 100644 --- a/scripts/bills_mongo2mysql.py +++ b/scripts/bills_mongo2mysql.py @@ -4,18 +4,21 @@ 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( @@ -27,11 +30,19 @@ def dealOneBill(bill): 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()) \ No newline at end of file + +asyncio.run(main()) diff --git a/scripts/labels_mongo2mysql.py b/scripts/labels_mongo2mysql.py index 064d795..69d4d14 100644 --- a/scripts/labels_mongo2mysql.py +++ b/scripts/labels_mongo2mysql.py @@ -5,43 +5,50 @@ mongo_url = 'http://www.fadinglight.cn:8088/class' mysql_url = 'http://localhost:8080/api/v1/label/' -async def getMongoBills(): +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 postBillsToMysql(bills): +async def postLabelsToMysql(label): async with aiohttp.ClientSession() as session: - async with session.post(mysql_url, json=bills) as response: + async with session.post(mysql_url, json=label) as response: data = await response.json() return data -def dealOneBill(bill): - bill.setdefault('type', 0) +def newLabel(name, type=0, relativeId=None): 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", + name=name, + type=type, + relativeId=relativeId, ) async def main(): - data = await getMongoBills() + data = await getMongoLabels() labels = data['data'] consumeLabels = labels['consume'] incomeLabels = labels['income'] - # for i in consumeLabels: + 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) -# bills = list(map(dealOneBill, bills)) -# respData = await postBillsToMysql(bills) -# print(respData) asyncio.run(main()) diff --git a/src/main/kotlin/cn/fadinglight/libs/Response.kt b/src/main/kotlin/cn/fadinglight/libs/Response.kt index b54f13a..814b7da 100644 --- a/src/main/kotlin/cn/fadinglight/libs/Response.kt +++ b/src/main/kotlin/cn/fadinglight/libs/Response.kt @@ -9,10 +9,10 @@ sealed class Resp { abstract fun json(): RespData class Ok(private val data: T) : Resp() { - override fun json() = RespData(code = 0, data = data, message = null) + override fun json() = RespData(code = 0, data = data, message = "") } - class Error(private val message: String?, val code: Int=-1) : Resp() { + class Error(private val message: String? = "", val code: Int = -1) : Resp() { override fun json(): RespData = RespData(code = code, data = null, message = message) } diff --git a/src/main/kotlin/cn/fadinglight/models/Label.kt b/src/main/kotlin/cn/fadinglight/models/Label.kt index 8521e00..c9240eb 100644 --- a/src/main/kotlin/cn/fadinglight/models/Label.kt +++ b/src/main/kotlin/cn/fadinglight/models/Label.kt @@ -2,15 +2,15 @@ package cn.fadinglight.models enum class LabelType { - CLASS, - LABEL, + CONSUME_CLASS, + CONSUME_LABEL, INCOME_CLASS; companion object { fun of(n: Int) = when (n) { - 0 -> LabelType.CLASS - 1 -> LabelType.LABEL - 2 -> LabelType.INCOME_CLASS + 0 -> CONSUME_CLASS + 1 -> CONSUME_LABEL + 2 -> INCOME_CLASS else -> throw IllegalArgumentException("error code $n") } } diff --git a/src/main/kotlin/cn/fadinglight/plugins/Database.kt b/src/main/kotlin/cn/fadinglight/plugins/Database.kt index 4ccd303..9675119 100644 --- a/src/main/kotlin/cn/fadinglight/plugins/Database.kt +++ b/src/main/kotlin/cn/fadinglight/plugins/Database.kt @@ -14,6 +14,10 @@ const val HIKARI_CONFIG_KEY = "ktor.hikariConfig" fun Application.configureDatabase() { val configPath = environment.config.property(HIKARI_CONFIG_KEY).getString() val dbConfig = HikariConfig(configPath) + val envs = System.getenv() + if (envs.containsKey("JDBC_URL")) { + dbConfig.jdbcUrl = envs["JDBC_URL"] + } val dataSource = HikariDataSource(dbConfig) Database.connect(dataSource) createTables() diff --git a/src/main/kotlin/cn/fadinglight/plugins/Routing.kt b/src/main/kotlin/cn/fadinglight/plugins/Routing.kt index e9d343b..998e2b5 100644 --- a/src/main/kotlin/cn/fadinglight/plugins/Routing.kt +++ b/src/main/kotlin/cn/fadinglight/plugins/Routing.kt @@ -11,7 +11,7 @@ fun Application.configureRouting() { routing { route("/") { get { - call.respond(LabelType.LABEL) + call.respond("Hello world") } } route("/api/v1") { diff --git a/src/main/kotlin/cn/fadinglight/routes/BillRoutes.kt b/src/main/kotlin/cn/fadinglight/routes/BillRoutes.kt index 799b760..f6edf91 100644 --- a/src/main/kotlin/cn/fadinglight/routes/BillRoutes.kt +++ b/src/main/kotlin/cn/fadinglight/routes/BillRoutes.kt @@ -37,6 +37,7 @@ fun Route.billRoute() { }.onSuccess { call.respond(Resp.Ok(it).json()) }.onFailure { + it.printStackTrace() call.respond(Resp.Error(it.message, code = -1).json()) } } diff --git a/src/main/kotlin/cn/fadinglight/services/BillServiceImpl.kt b/src/main/kotlin/cn/fadinglight/services/BillServiceImpl.kt index 3157357..ddbcb90 100644 --- a/src/main/kotlin/cn/fadinglight/services/BillServiceImpl.kt +++ b/src/main/kotlin/cn/fadinglight/services/BillServiceImpl.kt @@ -4,12 +4,15 @@ import cn.fadinglight.mapers.Bills import cn.fadinglight.mapers.Labels import cn.fadinglight.models.Bill import cn.fadinglight.models.BillType +import cn.fadinglight.models.LabelType import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope import org.jetbrains.exposed.sql.* 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.neq import org.jetbrains.exposed.sql.transactions.experimental.suspendedTransactionAsync import org.jetbrains.exposed.sql.transactions.transaction @@ -78,7 +81,6 @@ class BillServiceImpl : BillService { } override suspend fun addManyBills(bills: List): Int = transaction { - val newBills = Bills .batchInsert(bills) { this[Bills.type] = it.type.name @@ -91,13 +93,19 @@ class BillServiceImpl : BillService { .map(::resultRowToBill) newBills.forEach { val classId = Labels - .select(Labels.name eq it.cls) + .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 } - .single() - val labelId = Labels - .select(Labels.name eq it.label) + .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 } - .single() + .singleOrNull() + else null Labels.update({ (Labels.id eq labelId) or (Labels.id eq classId) }) { with(SqlExpressionBuilder) { it[count] = count + 1 diff --git a/src/main/kotlin/cn/fadinglight/services/LabelServiceImpl.kt b/src/main/kotlin/cn/fadinglight/services/LabelServiceImpl.kt index 1c9da11..3628962 100644 --- a/src/main/kotlin/cn/fadinglight/services/LabelServiceImpl.kt +++ b/src/main/kotlin/cn/fadinglight/services/LabelServiceImpl.kt @@ -24,17 +24,21 @@ class LabelServiceImpl : LabelService { .map(::resultRowToLabel) .groupBy { it.type } } - val consumeLabels = labelGroups[LabelType.CLASS] + val consumeLabels = labelGroups[LabelType.CONSUME_CLASS] + ?.sortedByDescending { it.count } ?.map { it.vo().apply { - this.labels = labelGroups[LabelType.LABEL] + this.labels = labelGroups[LabelType.CONSUME_LABEL] ?.filter { it2 -> it2.relativeId == it.id } - ?.map(Label::vo) - ?: emptyList() + ?.sortedByDescending { it2 -> it2.count } + ?.map { it2 -> it2.name } } - } ?: emptyList() + } + ?: emptyList() val incomeLabels = labelGroups[LabelType.INCOME_CLASS] - ?.map(Label::vo) ?: emptyList() + ?.sortedByDescending { it.count } + ?.map(Label::vo) + ?: emptyList() return LabelGroup(income = incomeLabels, consume = consumeLabels) } diff --git a/src/main/kotlin/cn/fadinglight/vo/LabelVO.kt b/src/main/kotlin/cn/fadinglight/vo/LabelVO.kt index 31bf96c..db2bdff 100644 --- a/src/main/kotlin/cn/fadinglight/vo/LabelVO.kt +++ b/src/main/kotlin/cn/fadinglight/vo/LabelVO.kt @@ -23,8 +23,7 @@ fun LabelPost.label() = Label( @Serializable data class LabelVO( val name: String, - val count: Int, - var labels: List?, + var labels: List?, ) @Serializable @@ -36,6 +35,5 @@ data class LabelGroup( fun Label.vo() = LabelVO( name = name, - count = count, - labels = emptyList(), + labels = null, ) diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index b819589..495bdff 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -2,7 +2,7 @@ ktor { development = true deployment { - port = 8080 + port = 4000 port = ${?PORT} watch = [ bill-ktor ] } diff --git a/src/main/resources/db.properties b/src/main/resources/db.properties index bc64379..0b82a68 100644 --- a/src/main/resources/db.properties +++ b/src/main/resources/db.properties @@ -1,4 +1,4 @@ driverClassName=org.mariadb.jdbc.Driver -jdbcUrl=jdbc:mariadb://localhost:3306/bill +jdbcUrl=jdbc:mariadb://www.fadinglight.cn:3306/bill dataSource.user=root dataSource.password=123456 \ No newline at end of file