feat🔫: 账单的基本操作
This commit is contained in:
parent
371359430f
commit
76e1f5d9ec
75
.gitignore
vendored
75
.gitignore
vendored
|
@ -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
|
|
@ -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")
|
||||
|
|
|
@ -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:
|
|
@ -14,5 +14,5 @@ fun Application.module() {
|
|||
configureRouting()
|
||||
configureSession()
|
||||
configureWebSocket()
|
||||
// configureDatabase()
|
||||
configureDatabase()
|
||||
}
|
36
src/main/kotlin/cn/fadinglight/dao/BillDao.kt
Normal file
36
src/main/kotlin/cn/fadinglight/dao/BillDao.kt
Normal 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,
|
||||
)
|
7
src/main/kotlin/cn/fadinglight/dao/LabelDao.kt
Normal file
7
src/main/kotlin/cn/fadinglight/dao/LabelDao.kt
Normal file
|
@ -0,0 +1,7 @@
|
|||
package cn.fadinglight.dao
|
||||
|
||||
data class LabelDao(
|
||||
val name: String,
|
||||
val count: Int,
|
||||
val labels: List<LabelDao>?
|
||||
)
|
19
src/main/kotlin/cn/fadinglight/libs/Response.kt
Normal file
19
src/main/kotlin/cn/fadinglight/libs/Response.kt
Normal 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)
|
||||
}
|
||||
|
||||
}
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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?,
|
||||
)
|
|
@ -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,
|
||||
)
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
|
87
src/main/kotlin/cn/fadinglight/services/BillServiceImpl.kt
Normal file
87
src/main/kotlin/cn/fadinglight/services/BillServiceImpl.kt
Normal 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 }
|
||||
}
|
||||
|
||||
|
||||
}
|
12
src/main/kotlin/cn/fadinglight/services/LabelServe.kt
Normal file
12
src/main/kotlin/cn/fadinglight/services/LabelServe.kt
Normal 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
|
||||
}
|
|
@ -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
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue
Block a user