新增法定调休开关,默认禁用,排班接管右上角

ViewModel 增加 showLegalHoliday 状态,默认 false。
关闭时:排班从左上角移到右上角,不显示法定调休角标。
开启时:回到旧布局,左上角=排班、右上角=法定调休。
DayCell 与各 Pager 透传新参数,预留后续接入设置页。
This commit is contained in:
meyou 2026-05-16 19:29:06 +08:00
parent ecf4cf601e
commit 043bd9824b
6 changed files with 35 additions and 4 deletions

View File

@ -90,6 +90,12 @@ class CalendarViewModel(
fun shiftKindAt(date: LocalDate): ShiftKind? = shiftPattern?.kindAt(date) fun shiftKindAt(date: LocalDate): ShiftKind? = shiftPattern?.kindAt(date)
/**
* 是否在右上角显示法定调休角标默认禁用,此时右上角让位给个人排班
* 开启后回到旧版布局:左上角=排班,右上角=法定调休后续接入设置页持久化
*/
var showLegalHoliday by mutableStateOf(false)
/** /**
* 选中指定日期 * 选中指定日期
* *

View File

@ -38,6 +38,8 @@ import plus.rua.project.ShiftKind
* @param collapseProgress 折叠进度0f=展开1f=折叠 * @param collapseProgress 折叠进度0f=展开1f=折叠
* @param rowHeightPx 从外层传入的锁定行高像素折叠过程中不变 * @param rowHeightPx 从外层传入的锁定行高像素折叠过程中不变
* @param effectiveWeeks 当前有效行数含翻页插值用于计算总高度 * @param effectiveWeeks 当前有效行数含翻页插值用于计算总高度
* @param shiftKindAt 日期 个人轮班类型的查询闭包
* @param showLegalHoliday 是否显示法定调休角标详见 [DayCell] 的同名参数
* @param onRowHeightMeasured 首次行高测量回调外层据此锁定行高 * @param onRowHeightMeasured 首次行高测量回调外层据此锁定行高
* @param modifier 外部布局修饰符 * @param modifier 外部布局修饰符
*/ */
@ -52,6 +54,7 @@ fun CalendarMonthPage(
rowHeightPx: Int, rowHeightPx: Int,
effectiveWeeks: Float, effectiveWeeks: Float,
shiftKindAt: (LocalDate) -> ShiftKind?, shiftKindAt: (LocalDate) -> ShiftKind?,
showLegalHoliday: Boolean,
onRowHeightMeasured: ((Int) -> Unit)? = null, onRowHeightMeasured: ((Int) -> Unit)? = null,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
@ -155,6 +158,7 @@ fun CalendarMonthPage(
isSelected = dayData.date == selectedDate, isSelected = dayData.date == selectedDate,
isToday = dayData.date == today, isToday = dayData.date == today,
shiftKind = shiftKindAt(dayData.date), shiftKind = shiftKindAt(dayData.date),
showLegalHoliday = showLegalHoliday,
onClick = { onDateClick(dayData.date) }, onClick = { onDateClick(dayData.date) },
modifier = Modifier.weight(1f) modifier = Modifier.weight(1f)
) )

View File

@ -260,6 +260,7 @@ fun CalendarMonthView(
viewModel.selectDate(date) viewModel.selectDate(date)
}, },
shiftKindAt = { date -> viewModel.shiftKindAt(date) }, shiftKindAt = { date -> viewModel.shiftKindAt(date) },
showLegalHoliday = viewModel.showLegalHoliday,
modifier = pagerModifier modifier = pagerModifier
) )
} else { } else {
@ -277,6 +278,7 @@ fun CalendarMonthView(
rowHeightPx = rowHeightPx, rowHeightPx = rowHeightPx,
effectiveWeeks = effectiveWeeks, effectiveWeeks = effectiveWeeks,
shiftKindAt = { date -> viewModel.shiftKindAt(date) }, shiftKindAt = { date -> viewModel.shiftKindAt(date) },
showLegalHoliday = viewModel.showLegalHoliday,
onRowHeightMeasured = { h -> onRowHeightMeasured = { h ->
if (h > 0) rowHeightPx = h if (h > 0) rowHeightPx = h
}, },

View File

@ -30,6 +30,8 @@ import kotlin.math.abs
* @param collapseProgress 折叠进度0f=展开1f=折叠 * @param collapseProgress 折叠进度0f=展开1f=折叠
* @param rowHeightPx 锁定行高像素 * @param rowHeightPx 锁定行高像素
* @param effectiveWeeks 当前有效行数含翻页插值 * @param effectiveWeeks 当前有效行数含翻页插值
* @param shiftKindAt 日期 个人轮班类型的查询闭包
* @param showLegalHoliday 是否显示法定调休角标详见 [DayCell] 的同名参数
* @param onRowHeightMeasured 首次行高测量回调 * @param onRowHeightMeasured 首次行高测量回调
* @param pagerState 外层共享的 PagerState用于保持翻页状态 * @param pagerState 外层共享的 PagerState用于保持翻页状态
* @param modifier 外部布局修饰符 * @param modifier 外部布局修饰符
@ -44,6 +46,7 @@ fun CalendarPager(
rowHeightPx: Int, rowHeightPx: Int,
effectiveWeeks: Float, effectiveWeeks: Float,
shiftKindAt: (LocalDate) -> ShiftKind?, shiftKindAt: (LocalDate) -> ShiftKind?,
showLegalHoliday: Boolean,
onRowHeightMeasured: ((Int) -> Unit)? = null, onRowHeightMeasured: ((Int) -> Unit)? = null,
pagerState: PagerState, pagerState: PagerState,
modifier: Modifier = Modifier modifier: Modifier = Modifier
@ -97,6 +100,7 @@ fun CalendarPager(
rowHeightPx = rowHeightPx, rowHeightPx = rowHeightPx,
effectiveWeeks = effectiveWeeks, effectiveWeeks = effectiveWeeks,
shiftKindAt = shiftKindAt, shiftKindAt = shiftKindAt,
showLegalHoliday = showLegalHoliday,
onRowHeightMeasured = onRowHeightMeasured, onRowHeightMeasured = onRowHeightMeasured,
modifier = Modifier.alpha(alpha) modifier = Modifier.alpha(alpha)
) )

View File

@ -49,7 +49,10 @@ enum class DayCellState {
* @param isCurrentMonth 是否属于当前显示月份 * @param isCurrentMonth 是否属于当前显示月份
* @param isSelected 是否为选中日期 * @param isSelected 是否为选中日期
* @param isToday 是否为今天 * @param isToday 是否为今天
* @param shiftKind 个人轮班类型,左上角胶囊显示;null 表示不显示与法定调休完全独立 * @param shiftKind 个人轮班类型;null 表示不显示与法定调休完全独立
* @param showLegalHoliday 是否显示法定调休角标
* false(默认):排班放右上角,左上角空白,不显示法定调休
* true:排班放左上角,法定调休放右上角(旧版布局)
* @param onClick 点击回调 * @param onClick 点击回调
* @param modifier 外部布局修饰符 * @param modifier 外部布局修饰符
*/ */
@ -60,6 +63,7 @@ fun DayCell(
isSelected: Boolean, isSelected: Boolean,
isToday: Boolean, isToday: Boolean,
shiftKind: ShiftKind?, shiftKind: ShiftKind?,
showLegalHoliday: Boolean,
onClick: () -> Unit, onClick: () -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
@ -259,6 +263,13 @@ fun DayCell(
} }
val shiftLabel = if (shiftKind == ShiftKind.WORK) "" else "" val shiftLabel = if (shiftKind == ShiftKind.WORK) "" else ""
val shiftAlpha = if (isCurrentMonth) 1f else 0.38f val shiftAlpha = if (isCurrentMonth) 1f else 0.38f
// showLegalHoliday=true 时排班让位左上角,法定调休占右上角;否则排班独占右上角
val shiftAlignment = if (showLegalHoliday) Alignment.TopStart else Alignment.TopEnd
val shiftPadding = if (showLegalHoliday) {
Modifier.padding(top = 1.dp, start = 2.dp)
} else {
Modifier.padding(top = 1.dp, end = 2.dp)
}
Text( Text(
text = shiftLabel, text = shiftLabel,
color = shiftFgColor.copy(alpha = shiftAlpha), color = shiftFgColor.copy(alpha = shiftAlpha),
@ -266,14 +277,14 @@ fun DayCell(
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
lineHeight = 9.sp, lineHeight = 9.sp,
modifier = Modifier modifier = Modifier
.align(Alignment.TopStart) .align(shiftAlignment)
.zIndex(1f) .zIndex(1f)
.padding(top = 1.dp, start = 2.dp) .then(shiftPadding)
.background(shiftBgColor.copy(alpha = shiftAlpha), CircleShape) .background(shiftBgColor.copy(alpha = shiftAlpha), CircleShape)
.padding(horizontal = 2.dp) .padding(horizontal = 2.dp)
) )
} }
if (holidayBadge != null) { if (showLegalHoliday && holidayBadge != null) {
Text( Text(
text = holidayBadge, text = holidayBadge,
color = holidayBadgeColor.copy(alpha = holidayBadgeAlpha), color = holidayBadgeColor.copy(alpha = holidayBadgeAlpha),

View File

@ -28,6 +28,8 @@ import kotlin.math.abs
* @param today 今天的日期 * @param today 今天的日期
* @param onDateClick 日期点击回调 * @param onDateClick 日期点击回调
* @param onWeekChanged 周切换回调滑动到新周时触发参数为该周周一日期 * @param onWeekChanged 周切换回调滑动到新周时触发参数为该周周一日期
* @param shiftKindAt 日期 个人轮班类型的查询闭包
* @param showLegalHoliday 是否显示法定调休角标详见 [DayCell] 的同名参数
* @param modifier 外部布局修饰符 * @param modifier 外部布局修饰符
*/ */
@Composable @Composable
@ -37,6 +39,7 @@ fun WeekPager(
onDateClick: (LocalDate) -> Unit, onDateClick: (LocalDate) -> Unit,
onWeekChanged: (LocalDate) -> Unit, onWeekChanged: (LocalDate) -> Unit,
shiftKindAt: (LocalDate) -> ShiftKind?, shiftKindAt: (LocalDate) -> ShiftKind?,
showLegalHoliday: Boolean,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val initialWeekMonday = remember { selectedDate.toWeekMonday() } val initialWeekMonday = remember { selectedDate.toWeekMonday() }
@ -85,6 +88,7 @@ fun WeekPager(
isSelected = date == selectedDate, isSelected = date == selectedDate,
isToday = date == today, isToday = date == today,
shiftKind = shiftKindAt(date), shiftKind = shiftKindAt(date),
showLegalHoliday = showLegalHoliday,
onClick = { onDateClick(date) }, onClick = { onDateClick(date) },
modifier = Modifier.weight(1f) modifier = Modifier.weight(1f)
) )