feat(shift): long-press flips and rephases subsequent days
长按语义从"设相位断点"改为"翻转该天并从次日起重排": - 翻转当天 override + 次日插入 PhaseBreak(重排起点) - 后续按 cycle 自动顺延,匹配用户直觉 - 再次长按同一天可撤销(移除 override + 关联断点) - 角标"断"改为"起",文案同步更新
This commit is contained in:
parent
14a3239b39
commit
66a054f2d8
@ -48,10 +48,11 @@ import plus.rua.project.ShiftKind
|
|||||||
import plus.rua.project.ShiftPattern
|
import plus.rua.project.ShiftPattern
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 班次设置页用的迷你月历。点某天翻转班/休,长按设/清相位断点。
|
* 班次设置页用的迷你月历。点某天翻转班/休(仅当天),长按翻转并从次日起重排周期。
|
||||||
*
|
*
|
||||||
* 月份可前后翻页,每格显示日期数字与班次角标(班/休/断)。
|
* 月份可前后翻页,每格显示日期数字与班次角标(班/休/起)。
|
||||||
* 点击翻转该天的班/休 override;长按切换相位断点。
|
* 点击翻转该天的班/休 override;长按翻转该天并在次日插入重排起点,
|
||||||
|
* 后续按 cycle 重新顺延。再次长按同一天可撤销。
|
||||||
*
|
*
|
||||||
* @param pattern 当前轮班配置(只读),由 [onPatternChange] 修改
|
* @param pattern 当前轮班配置(只读),由 [onPatternChange] 修改
|
||||||
* @param onPatternChange 修改后的新 pattern 回调
|
* @param onPatternChange 修改后的新 pattern 回调
|
||||||
@ -125,7 +126,7 @@ fun ShiftCalendarGrid(
|
|||||||
date = date,
|
date = date,
|
||||||
pattern = pattern,
|
pattern = pattern,
|
||||||
onClick = { onPatternChange(toggleOverride(pattern, date)) },
|
onClick = { onPatternChange(toggleOverride(pattern, date)) },
|
||||||
onLongClick = { onPatternChange(togglePhaseBreak(pattern, date)) },
|
onLongClick = { onPatternChange(toggleFlipAndRephase(pattern, date)) },
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@ -152,15 +153,38 @@ private fun toggleOverride(pattern: ShiftPattern, date: LocalDate): ShiftPattern
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换某天的相位断点:已有则清除,没有则新增(cycleOffset=0)。
|
* 翻转某天的班/休,并从次日起重排周期(后续按 cycle 重新顺延)。
|
||||||
|
*
|
||||||
|
* 实现:翻转该天 override + 在 [date] 次日插入 PhaseBreak(offset=0)。
|
||||||
|
* 次日成为新的 cycle[0],后续自动按周期顺延。
|
||||||
|
*
|
||||||
|
* 撤销:再次长按同一天,若存在由该天派生的断点(次日、offset=0),则移除 override 与该断点。
|
||||||
|
*
|
||||||
|
* @param date 被翻转并作为重排起点的日期
|
||||||
*/
|
*/
|
||||||
private fun togglePhaseBreak(pattern: ShiftPattern, date: LocalDate): ShiftPattern {
|
private fun toggleFlipAndRephase(pattern: ShiftPattern, date: LocalDate): ShiftPattern {
|
||||||
val existing = pattern.phaseBreaks.find { it.date == date }
|
val nextDay = date.plus(DatePeriod(days = 1))
|
||||||
return if (existing != null) {
|
val derivedBreak = pattern.phaseBreaks.find { it.date == nextDay && it.cycleOffset == 0 }
|
||||||
pattern.copy(phaseBreaks = pattern.phaseBreaks - existing)
|
|
||||||
} else {
|
if (derivedBreak != null) {
|
||||||
pattern.copy(phaseBreaks = pattern.phaseBreaks + PhaseBreak(date, 0))
|
// 撤销:移除该天的 override 与关联断点
|
||||||
|
return pattern.copy(
|
||||||
|
overrides = pattern.overrides - date,
|
||||||
|
phaseBreaks = pattern.phaseBreaks - derivedBreak
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 翻转该天 + 次日插入断点重排
|
||||||
|
val current = pattern.kindAt(date) ?: return pattern
|
||||||
|
val newVal = if (current == ShiftKind.WORK) ShiftKind.OFF else ShiftKind.WORK
|
||||||
|
val tempPattern = pattern.copy(overrides = pattern.overrides - date)
|
||||||
|
val base = tempPattern.kindAt(date)
|
||||||
|
val newOverrides = if (newVal == base) pattern.overrides - date
|
||||||
|
else pattern.overrides + (date to newVal)
|
||||||
|
return pattern.copy(
|
||||||
|
overrides = newOverrides,
|
||||||
|
phaseBreaks = pattern.phaseBreaks + PhaseBreak(nextDay, 0)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,16 +206,17 @@ private fun ShiftDayCell(
|
|||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
val kind = pattern.kindAt(date)
|
val kind = pattern.kindAt(date)
|
||||||
val isBreak = pattern.phaseBreaks.any { it.date == date }
|
// 断点在"翻转日的次日",表示该天为重排起点
|
||||||
|
val isRephaseStart = pattern.phaseBreaks.any { it.date == date && it.cycleOffset == 0 }
|
||||||
|
|
||||||
val badgeColor = when {
|
val badgeColor = when {
|
||||||
isBreak -> MaterialTheme.colorScheme.tertiary
|
isRephaseStart -> MaterialTheme.colorScheme.tertiary
|
||||||
kind == ShiftKind.WORK -> MaterialTheme.colorScheme.primary
|
kind == ShiftKind.WORK -> MaterialTheme.colorScheme.primary
|
||||||
kind == ShiftKind.OFF -> MaterialTheme.colorScheme.error
|
kind == ShiftKind.OFF -> MaterialTheme.colorScheme.error
|
||||||
else -> Color.Transparent
|
else -> Color.Transparent
|
||||||
}
|
}
|
||||||
val badgeText = when {
|
val badgeText = when {
|
||||||
isBreak -> "断"
|
isRephaseStart -> "起"
|
||||||
kind == ShiftKind.WORK -> "班"
|
kind == ShiftKind.WORK -> "班"
|
||||||
kind == ShiftKind.OFF -> "休"
|
kind == ShiftKind.OFF -> "休"
|
||||||
else -> ""
|
else -> ""
|
||||||
|
|||||||
@ -59,7 +59,7 @@ import kotlin.time.Instant
|
|||||||
* 页面结构三段:
|
* 页面结构三段:
|
||||||
* 1. 基础周期:锚点日期、当前周期展示;
|
* 1. 基础周期:锚点日期、当前周期展示;
|
||||||
* 2. 预设方案:1班1休 / 2班2休 / 3班3休 / 4班4休 快捷切换;
|
* 2. 预设方案:1班1休 / 2班2休 / 3班3休 / 4班4休 快捷切换;
|
||||||
* 3. 调班设置:迷你月历(点=翻转班/休,长按=设/清相位断点)+ 恢复默认。
|
* 3. 调班设置:迷你月历(点=翻转班/休,长按=翻转并从次日起重排)+ 恢复默认。
|
||||||
*
|
*
|
||||||
* @param onBack 返回回调(由 Activity 触发 finishWithSlideBack)
|
* @param onBack 返回回调(由 Activity 触发 finishWithSlideBack)
|
||||||
*/
|
*/
|
||||||
@ -156,12 +156,12 @@ fun ShiftPatternScreen(onBack: () -> Unit) {
|
|||||||
Text("调班设置", style = MaterialTheme.typography.titleSmall, fontWeight = FontWeight.SemiBold)
|
Text("调班设置", style = MaterialTheme.typography.titleSmall, fontWeight = FontWeight.SemiBold)
|
||||||
ShiftCalendarGrid(pattern = pattern, onPatternChange = { pattern = it })
|
ShiftCalendarGrid(pattern = pattern, onPatternChange = { pattern = it })
|
||||||
Text(
|
Text(
|
||||||
text = "点某天 = 翻转班/休,长按某天 = 设/清相位断点",
|
text = "点某天 = 翻转班/休(仅当天),长按某天 = 翻转并从次日起重排",
|
||||||
style = MaterialTheme.typography.labelSmall,
|
style = MaterialTheme.typography.labelSmall,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = "图例:班(蓝)/休(红)/断点(琥珀)",
|
text = "图例:班(蓝)/休(红)/重排起点(琥珀)",
|
||||||
style = MaterialTheme.typography.labelSmall,
|
style = MaterialTheme.typography.labelSmall,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user