feat🔫: 账单的基本操作

This commit is contained in:
车厘子 2022-10-28 05:02:55 +08:00
parent 371359430f
commit 76e1f5d9ec
16 changed files with 345 additions and 125 deletions

75
.gitignore vendored
View File

@ -1,36 +1,39 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Fleet ###
.fleet

View File

@ -50,6 +50,7 @@ dependencies {
// Session
implementation("io.ktor:ktor-server-sessions:$ktor_version")
implementation("io.ktor:ktor-server-auth:$ktor_version")
// Ktor
implementation("io.ktor:ktor-server-call-logging:$ktor_version")
implementation("io.ktor:ktor-server-content-negotiation-jvm:$ktor_version")

View File

@ -1,19 +1,21 @@
services:
db:
image: mariadb
restart: always
environment:
MARIADB_ROOT_PASSWORD: 123456
ports:
- 3306:3306
volumes:
- db-data:/var/lib/mysql
adminer:
image: adminer
restart: always
ports:
- 8081:8080
volumes:
services:
db:
container_name: bill-test-db
image: mariadb
restart: always
environment:
MARIADB_ROOT_PASSWORD: 123456
ports:
- 3306:3306
volumes:
- db-data:/var/lib/mysql
adminer:
container_name: bill-test-adminer
image: adminer
restart: always
ports:
- 8081:8080
volumes:
db-data:

View File

@ -14,5 +14,5 @@ fun Application.module() {
configureRouting()
configureSession()
configureWebSocket()
// configureDatabase()
configureDatabase()
}

View File

@ -0,0 +1,36 @@
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

@ -0,0 +1,7 @@
package cn.fadinglight.dao
data class LabelDao(
val name: String,
val count: Int,
val labels: List<LabelDao>?
)

View File

@ -0,0 +1,19 @@
package cn.fadinglight.libs
import kotlinx.serialization.Serializable
@Serializable
data class RespData<T>(val code: Int, val data: T?, val message: String?)
sealed class Resp<T> {
abstract fun json(): RespData<T>
class Ok<T>(val data: T) : Resp<T>() {
override fun json() = RespData<T>(code = 0, data = data, message = null)
}
class Error(val message: String?, val code: Int) : Resp<Unit>() {
override fun json(): RespData<Unit> = RespData(code = code, data = null, message = message)
}
}

View File

@ -1,19 +1,19 @@
package cn.fadinglight.mapers
import org.jetbrains.exposed.dao.id.IntIdTable
object Bills : IntIdTable() {
val type = integer("type")
val date = varchar("date", 15)
val money = integer("money")
val cls = varchar("cls", 31)
val label = varchar("label", 31)
val options = varchar("options", 255)
}
object Labels : IntIdTable() {
val name = varchar("name", 15)
val type = integer("type")
val relativeId = integer("relative_id")
val nums = integer("nums")
}
package cn.fadinglight.mapers
import org.jetbrains.exposed.dao.id.IntIdTable
object Bills : IntIdTable() {
val type = varchar("type", 15)
val date = varchar("date", 15)
val money = integer("money")
val cls = varchar("cls", 31)
val label = varchar("label", 31)
val options = varchar("options", 255).nullable()
}
object Labels : IntIdTable() {
val type = varchar("type", 15)
val name = varchar("name", 15)
val relativeId = integer("relative_id")
val nums = integer("nums")
}

View File

@ -1,15 +1,19 @@
package cn.fadinglight.models
enum class BillType {
Consume,
Income,
}
data class Bill(
var id: Int?,
var type: BillType,
val money: Int,
val cls: String,
val label: String,
val options: String?,
)
package cn.fadinglight.models
import kotlinx.serialization.Serializable
enum class BillType {
Consume,
Income,
}
@Serializable
data class Bill(
var id: Int?,
val type: BillType,
val date: String,
val money: Int,
val cls: String,
val label: String,
val options: String?,
)

View File

@ -1,4 +1,15 @@
package cn.fadinglight.models
class Label {
}
enum class LabelType {
CLASS,
LABEL,
}
data class Label(
var id: Int?,
val type: LabelType,
val name: String,
var count: Int,
val relativedId: Int,
)

View File

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

View File

@ -1,15 +1,18 @@
package cn.fadinglight.services
import cn.fadinglight.models.Bill
interface BillService {
fun getMonthBills(year: String, month: String): List<Bill>
}
class BillServiceImpl : BillService {
override fun getMonthBills(year: String, month: String): List<Bill> {
TODO("Not yet implemented")
}
}
package cn.fadinglight.services
import cn.fadinglight.models.Bill
interface BillService {
suspend fun getManyBills(year: String, month: String): List<Bill>
suspend fun getManyBills(year: String, month: String, day: String): List<Bill>
suspend fun getManyBills(): List<Bill>
suspend fun getOneBill(billId: Int): Bill
suspend fun addManyBills(bills: List<Bill>): Int
suspend fun addOneBill(bill: Bill): Int
suspend fun updateManyBills(bills: List<Bill>): Int
suspend fun updateOneBill(bill: Bill): Int
suspend fun deleteManyBills(bills: List<Bill>): Int
suspend fun deleteOneBill(billId: Int): Int
}

View File

@ -0,0 +1,87 @@
package cn.fadinglight.services
import cn.fadinglight.mapers.Bills
import cn.fadinglight.models.Bill
import cn.fadinglight.models.BillType
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.SqlExpressionBuilder.like
import org.jetbrains.exposed.sql.transactions.transaction
class BillServiceImpl : BillService {
private fun resultRowToBill(row: ResultRow) = Bill(
id = row[Bills.id].value,
type = BillType.valueOf(row[Bills.type]),
date = row[Bills.date],
money = row[Bills.money],
cls = row[Bills.cls],
label = row[Bills.label],
options = row[Bills.options]
)
override suspend fun getManyBills(year: String, month: String): List<Bill> = transaction {
Bills.select(Bills.date like "%${year}-${month}%").map(::resultRowToBill)
}
override suspend fun getManyBills(year: String, month: String, day: String): List<Bill> = transaction {
Bills.select(Bills.date eq "${year}-${month}-${day}").map(::resultRowToBill)
}
override suspend fun getManyBills(): List<Bill> = transaction {
Bills.selectAll().map(::resultRowToBill)
}
override suspend fun getOneBill(billId: Int): Bill = transaction {
Bills.select(Bills.id eq billId).single().let(::resultRowToBill)
}
override suspend fun addOneBill(bill: Bill): Int = transaction {
Bills.insertAndGetId {
it[type] = bill.type.name
it[date] = bill.date
it[cls] = bill.cls
it[label] = bill.label
it[money] = bill.money
it[options] = bill.options
}.value
}
override suspend fun addManyBills(bills: List<Bill>): Int = transaction {
Bills.batchInsert(bills) {
this[Bills.type] = it.type.name
this[Bills.date] = it.date
this[Bills.cls] = it.cls
this[Bills.label] = it.label
this[Bills.money] = it.money
this[Bills.options] = it.options
}.count()
}
override suspend fun updateManyBills(bills: List<Bill>): Int {
TODO("Not yet implemented")
}
override suspend fun updateOneBill(bill: Bill) = transaction {
Bills.update({ Bills.id eq bill.id }) {
it[type] = bill.type.name
it[date] = bill.date
it[money] = bill.money
it[cls] = bill.cls
it[label] = bill.label
it[options] = bill.options
}
}
override suspend fun deleteManyBills(bills: List<Bill>): Int {
TODO("Not yet implemented")
}
override suspend fun deleteOneBill(billId: Int): Int = transaction {
Bills.deleteWhere { Bills.id eq billId }
}
}

View File

@ -0,0 +1,12 @@
package cn.fadinglight.services
import cn.fadinglight.dao.LabelDao
import cn.fadinglight.models.Label
import cn.fadinglight.models.LabelType
interface LabelServe {
suspend fun getLabels(): List<LabelDao>
suspend fun addLabel(labelType: LabelType, label: Label): Boolean
suspend fun deleteLabel(labelId: Int): Boolean
suspend fun addCount(labelId: Int): Boolean
}

View File

@ -1,4 +1,4 @@
driverClassName=org.mariadb.jdbc.Driver
jdbcUrl=jdbc:mariadb://localhost:3306/bill
dataSource.user=root
driverClassName=org.mariadb.jdbc.Driver
jdbcUrl=jdbc:mariadb://localhost:3306/bill
dataSource.user=root
dataSource.password=123456

View File

@ -1,12 +1,12 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="trace">
<appender-ref ref="STDOUT"/>
</root>
<logger name="io.netty" level="INFO"/>
<logger name="com.zaxxer.hikari" level="ERROR"/>
</configuration>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
<logger name="io.netty" level="INFO"/>
<logger name="com.zaxxer.hikari" level="ERROR"/>
</configuration>