Skip to content

Commit 0359409

Browse files
authored
合并拉取请求 #1
增加月份统计、优化统计表现形式
1 parent 6d316e5 commit 0359409

18 files changed

+647
-118
lines changed

.idea/runConfigurations/MainKt.xml

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ val appName = "StopBonus"
1212
val appPackage = "love.forte.bonus"
1313
val appMenuGroup = "forteApp"
1414
val appNameWithPackage = "$appPackage.$appName"
15-
val appVersion = "1.0.6"
15+
val appVersion = "1.0.7"
1616

1717
group = appPackage
1818
version = appVersion

src/main/kotlin/Main.kt

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ import kotlin.io.path.Path
2222
import kotlin.io.path.pathString
2323

2424
fun storeAppPath(): Path {
25+
if (System.getenv("DEBUG").toBoolean() || System.getProperty("debug").toBoolean()) {
26+
return Path("./data")
27+
}
28+
2529
val localAppData = System.getenv("LOCALAPPDATA")
2630
if (localAppData != null) {
2731
return Path(localAppData, "StopBonus", "data")

src/main/kotlin/database/entity/Account.kt

+14
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ object Accounts : BaseIntIdTable() {
1414

1515
class Account(id: EntityID<Int>) : BaseIntEntity(id, Accounts) {
1616
companion object : BaseEntityClass<Account>(Accounts)
17+
1718
var name by Accounts.name
1819

1920
val records by BonusRecord referrersOn BonusRecords.account
@@ -27,3 +28,16 @@ fun Table.referenceAccount(
2728
fkName: String? = null
2829
): Column<EntityID<Int>> =
2930
reference(columnName, Accounts, onDelete, onUpdate, fkName)
31+
32+
33+
data class AccountView(
34+
override val entityID: EntityID<Int>,
35+
val name: String,
36+
) : BaseIntEntityView
37+
38+
fun Account.toView(
39+
name: String = this.name,
40+
): AccountView = AccountView(
41+
id,
42+
name = name,
43+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package database.entity
2+
3+
import org.jetbrains.exposed.dao.DaoEntityID
4+
import org.jetbrains.exposed.dao.id.EntityID
5+
6+
7+
/**
8+
*
9+
* @author ForteScarlet
10+
*/
11+
interface BaseEntityView<ID : Comparable<ID>> {
12+
val entityID: EntityID<ID>
13+
val id: ID
14+
get() = entityID.value
15+
16+
}
17+
18+
/**
19+
*
20+
* @author ForteScarlet
21+
*/
22+
interface BaseIntEntityView : BaseEntityView<Int>

src/main/kotlin/database/entity/BonusRecord.kt

+25
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import org.jetbrains.exposed.sql.ReferenceOption
55
import org.jetbrains.exposed.sql.Table
66
import org.jetbrains.exposed.sql.javatime.duration
77
import org.jetbrains.exposed.sql.javatime.timestamp
8+
import java.time.Duration
9+
import java.time.Instant
810

911
/**
1012
* 奖励记录
@@ -64,3 +66,26 @@ object BonusRecordWeapons : Table() {
6466
override val primaryKey: PrimaryKey = PrimaryKey(record, weapon)
6567
}
6668

69+
data class BonusRecordView(
70+
override val entityID: EntityID<Int>,
71+
val startTime: Instant,
72+
val endTime: Instant,
73+
val duration: Duration,
74+
val score: UInt,
75+
val weapons: List<WeaponView>
76+
) : BaseIntEntityView
77+
78+
fun BonusRecord.toView(
79+
startTime: Instant = this.startTime,
80+
endTime: Instant = this.endTime,
81+
duration: Duration = this.duration,
82+
score: UInt = this.score,
83+
weapons: List<WeaponView> = this.weapons.map { it.toView() }
84+
): BonusRecordView = BonusRecordView(
85+
entityID = id,
86+
startTime = startTime,
87+
endTime = endTime,
88+
duration = duration,
89+
score = score,
90+
weapons = weapons,
91+
)

src/main/kotlin/database/entity/Weapon.kt

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
package database.entity
22

33
import org.jetbrains.exposed.dao.id.EntityID
4-
import org.jetbrains.exposed.sql.ReferenceOption
5-
import org.jetbrains.exposed.sql.Table
64

7-
//region 配菜
85
/**
9-
* 配菜信息
6+
* 武器信息
107
*/
118
object Weapons : BaseIntIdTable() {
129
val account = referenceAccount()
@@ -22,5 +19,16 @@ class Weapon(id: EntityID<Int>) : BaseIntEntity(id, Weapons) {
2219
var account by Account referencedOn Weapons.account
2320
var name by Weapons.name
2421
}
25-
//endregion
2622

23+
24+
data class WeaponView(
25+
override val entityID: EntityID<Int>,
26+
val name: String
27+
) : BaseIntEntityView
28+
29+
fun Weapon.toView(
30+
name: String = this.name,
31+
): WeaponView = WeaponView(
32+
entityID = id,
33+
name = name
34+
)

src/main/kotlin/view/App.kt

+2-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import androidx.compose.foundation.hoverable
99
import androidx.compose.foundation.interaction.MutableInteractionSource
1010
import androidx.compose.foundation.interaction.collectIsHoveredAsState
1111
import androidx.compose.foundation.layout.Column
12-
import androidx.compose.material.ExperimentalMaterialApi
1312
import androidx.compose.material.Icon
1413
import androidx.compose.material.Text
1514
import androidx.compose.material.icons.Icons
@@ -28,7 +27,7 @@ import androidx.compose.ui.unit.TextUnitType
2827
import androidx.compose.ui.window.FrameWindowScope
2928
import androidx.compose.ui.window.WindowState
3029
import database.DatabaseOperator
31-
import database.entity.Account
30+
import database.entity.AccountView
3231
import kotlinx.coroutines.CoroutineScope
3332
import view.account.AccountHome
3433
import view.account.AccountState
@@ -47,7 +46,7 @@ class AppState(
4746
@Composable
4847
@Preview
4948
fun FrameWindowScope.App(appState: AppState) {
50-
val targetAccount = remember { mutableStateOf<Account?>(null) }
49+
val targetAccount = remember { mutableStateOf<AccountView?>(null) }
5150

5251
AnimatedContent(targetAccount.value) { account ->
5352
when (account) {

src/main/kotlin/view/account/AccountAction.kt

-14
This file was deleted.

src/main/kotlin/view/account/AccountDetailView.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
package view.account
22

3-
import androidx.compose.foundation.border
4-
import androidx.compose.foundation.layout.*
5-
import androidx.compose.material.ExperimentalMaterialApi
3+
import androidx.compose.foundation.layout.Arrangement
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.fillMaxWidth
6+
import androidx.compose.foundation.layout.padding
67
import androidx.compose.material.Text
78
import androidx.compose.material3.HorizontalDivider
89
import androidx.compose.material3.NavigationDrawerItem
910
import androidx.compose.runtime.Composable
1011
import androidx.compose.ui.Alignment
1112
import androidx.compose.ui.Modifier
12-
import androidx.compose.ui.graphics.Color
1313
import androidx.compose.ui.unit.dp
1414

1515
@Composable

src/main/kotlin/view/account/AccountHome.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import androidx.compose.runtime.*
88
import androidx.compose.ui.Modifier
99
import androidx.compose.ui.unit.dp
1010
import database.DatabaseOperator
11-
import database.entity.Account
11+
import database.entity.AccountView
1212
import org.jetbrains.exposed.sql.Transaction
1313
import view.AppState
1414
import view.account.home.AccountHomeView
@@ -21,15 +21,15 @@ import kotlin.coroutines.CoroutineContext
2121
class AccountState(
2222
val appState: AppState,
2323
val database: DatabaseOperator,
24-
val account: Account,
25-
val accountState: MutableState<Account?>,
24+
val account: AccountView,
25+
val accountState: MutableState<AccountView?>,
2626
) {
2727
var accountOrNull by accountState
2828

2929
suspend inline fun <T> inAccountTransaction(
3030
context: CoroutineContext? = null,
3131
transactionIsolation: Int? = null,
32-
crossinline block: suspend Transaction.(Account) -> T
32+
crossinline block: suspend Transaction.(AccountView) -> T
3333
): T {
3434
return account.let { a ->
3535
database.inSuspendedTransaction(context, transactionIsolation) {

src/main/kotlin/view/account/home/AccountHomeView.kt

+10-12
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@ import androidx.compose.ui.unit.TextUnit
2222
import androidx.compose.ui.unit.TextUnitType
2323
import androidx.compose.ui.unit.dp
2424
import androidx.compose.ui.window.PopupProperties
25-
import database.entity.Account
26-
import database.entity.BonusRecord
27-
import database.entity.Weapon
28-
import database.entity.Weapons
25+
import database.entity.*
2926
import kotlinx.coroutines.launch
3027
import org.jetbrains.exposed.sql.SizedCollection
3128
import view.account.AccountViewPage
@@ -111,7 +108,7 @@ private fun AccountHome(state: PageViewState) {
111108
initialMinute = nowTime.minute
112109
)
113110

114-
var weapon by remember { mutableStateOf<Weapon?>(null) }
111+
var weapon by remember { mutableStateOf<WeaponView?>(null) }
115112
val score = remember { SliderState(value = 10f, steps = 8, valueRange = 1f..10f) }
116113

117114
suspend fun clearStates() {
@@ -287,15 +284,16 @@ private fun AccountHome(state: PageViewState) {
287284

288285

289286
BonusRecord.new {
290-
this.account = account
287+
this.account = Account.findById(account.id)!! // TODO null ?
291288
this.duration = duration
292289
this.startTime =
293290
ZonedDateTime.of(selectedStartDateTime, ZoneId.systemDefault()).toInstant()
294291
this.endTime =
295292
ZonedDateTime.of(selectedEndDateTime, ZoneId.systemDefault()).toInstant()
296293
this.score = score.value.toUInt()
297294
weapon?.also { w ->
298-
this.weapons = SizedCollection(listOf(w))
295+
this.weapons = SizedCollection(listOf(Weapon.findById(w.id)!!))
296+
// TODO null?
299297
}
300298
}
301299
}
@@ -358,14 +356,14 @@ private fun AccountHome(state: PageViewState) {
358356
@OptIn(ExperimentalMaterial3Api::class)
359357
@Composable
360358
private inline fun WeaponSelector(
361-
state: PageViewState, selectedWeapon: Weapon?,
362-
crossinline onSelect: (Weapon?) -> Unit
359+
state: PageViewState, selectedWeapon: WeaponView?,
360+
crossinline onSelect: (WeaponView?) -> Unit
363361
) {
364-
val weapons = remember { mutableStateListOf<Weapon>() }
362+
val weapons = remember { mutableStateListOf<WeaponView>() }
365363
LaunchedEffect(state) {
366-
state.accountState.inAccountTransaction { account: Account ->
364+
state.accountState.inAccountTransaction { account ->
367365
val all = Weapon.find { Weapons.account eq account.id }
368-
.notForUpdate()
366+
.notForUpdate().map { it.toView() }
369367

370368
weapons.addAll(all)
371369
}

src/main/kotlin/view/account/record/AccountBonusRecordView.kt

+15-26
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,18 @@ import androidx.compose.ui.draw.clip
2323
import androidx.compose.ui.graphics.Color
2424
import androidx.compose.ui.unit.dp
2525
import database.entity.BonusRecord
26-
import database.entity.BonusRecordWeapons.weapon
26+
import database.entity.BonusRecordView
2727
import database.entity.BonusRecords
28-
import database.entity.Weapon
28+
import database.entity.toView
2929
import kotlinx.coroutines.CoroutineScope
3030
import kotlinx.coroutines.launch
3131
import org.jetbrains.exposed.dao.with
3232
import org.jetbrains.exposed.sql.SortOrder
3333
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
3434
import org.jetbrains.exposed.sql.deleteWhere
35-
import org.jetbrains.exposed.sql.mapLazy
3635
import view.account.AccountViewPage
3736
import view.account.PageViewState
3837
import java.time.Duration
39-
import java.time.Instant
4038
import java.time.ZoneId
4139

4240

@@ -75,37 +73,28 @@ var account by Account referencedOn BonusRecords.account
7573
var weapons by Weapon via BonusRecordWeapons
7674
*/
7775

78-
private data class RecordData(
79-
val id: Int,
80-
val startTime: Instant,
81-
val endTime: Instant,
82-
val duration: Duration,
83-
val score: UInt,
84-
val weapons: List<Weapon>
85-
)
76+
// private data class RecordData(
77+
// val id: Int,
78+
// val startTime: Instant,
79+
// val endTime: Instant,
80+
// val duration: Duration,
81+
// val score: UInt,
82+
// val weapons: List<WeaponView>
83+
// )
8684

8785
@Composable
8886
private fun ShowBonusRecordList(state: PageViewState) {
8987
val scope = rememberCoroutineScope()
90-
val recordList = remember { mutableStateListOf<RecordData>() }
88+
val recordList = remember { mutableStateListOf<BonusRecordView>() }
9189
val listState = rememberLazyListState()
9290

9391
LaunchedEffect(Unit) {
9492
state.accountState.inAccountTransaction { account ->
95-
val all = account.records
93+
val all = BonusRecord.find { BonusRecords.account eq account.id }
9694
.orderBy(BonusRecords.createTime to SortOrder.DESC)
9795
.with(BonusRecord::weapons)
9896
.notForUpdate()
99-
.mapLazy {
100-
RecordData(
101-
id = it.id.value,
102-
startTime = it.startTime,
103-
endTime = it.endTime,
104-
duration = it.duration,
105-
score = it.score,
106-
weapons = it.weapons.toList(),
107-
)
108-
}
97+
.map { it.toView() }
10998

11099
recordList.addAll(all)
111100
}
@@ -125,8 +114,8 @@ private fun ShowBonusRecordList(state: PageViewState) {
125114
private fun ListItemRecord(
126115
state: PageViewState,
127116
scope: CoroutineScope,
128-
record: RecordData,
129-
onDelete: (RecordData) -> Unit,
117+
record: BonusRecordView,
118+
onDelete: (BonusRecordView) -> Unit,
130119
) {
131120
val interactionSource = remember { MutableInteractionSource() }
132121
val isHovered by interactionSource.collectIsHoveredAsState()

0 commit comments

Comments
 (0)