feat: 完成员工排班模块并统一门店抽屉底部操作样式
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 文件职责:周排班看板。
|
||||
* 1. 展示各员工周排班只读视图。
|
||||
* 2. 提供“编辑排班”入口。
|
||||
*/
|
||||
import type { ShiftType, StaffDayShiftDto } from '#/api/store-staff';
|
||||
import type { DayOption, WeekEditorRow } from '#/views/store/staff/types';
|
||||
|
||||
import { Button, Card, Empty } from 'ant-design-vue';
|
||||
|
||||
interface Props {
|
||||
dayOptions: DayOption[];
|
||||
getShiftClass: (shiftType: ShiftType) => string;
|
||||
getShiftLabel: (shiftType: ShiftType) => string;
|
||||
getShiftTimeText: (shift: StaffDayShiftDto) => string;
|
||||
roleLabelResolver: (roleType: WeekEditorRow['roleType']) => string;
|
||||
rows: WeekEditorRow[];
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'editWeek'): void;
|
||||
}>();
|
||||
|
||||
/** 读取员工某日排班,缺失时兜底为休息。 */
|
||||
function resolveDayShift(
|
||||
row: WeekEditorRow,
|
||||
dayOfWeek: number,
|
||||
): StaffDayShiftDto {
|
||||
return (
|
||||
row.shifts.find((item) => item.dayOfWeek === dayOfWeek) ?? {
|
||||
dayOfWeek,
|
||||
shiftType: 'off',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
}
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Card :bordered="false" class="staff-card">
|
||||
<template #title>
|
||||
<span class="section-title">本周排班</span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<Button @click="emit('editWeek')">编辑排班</Button>
|
||||
</template>
|
||||
|
||||
<div v-if="props.rows.length === 0" class="schedule-empty">
|
||||
<Empty description="暂无可排班员工" />
|
||||
</div>
|
||||
|
||||
<div v-else class="schedule-board-wrap">
|
||||
<table class="schedule-board-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>员工</th>
|
||||
<th v-for="day in props.dayOptions" :key="day.dayOfWeek">
|
||||
{{ day.label }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="row in props.rows" :key="row.staffId">
|
||||
<td class="schedule-staff-cell">
|
||||
<div class="schedule-staff-name">{{ row.staffName }}</div>
|
||||
<div class="schedule-staff-role">
|
||||
{{ props.roleLabelResolver(row.roleType) }}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td
|
||||
v-for="day in props.dayOptions"
|
||||
:key="`${row.staffId}-${day.dayOfWeek}`"
|
||||
>
|
||||
<div
|
||||
class="schedule-cell"
|
||||
:class="
|
||||
props.getShiftClass(
|
||||
resolveDayShift(row, day.dayOfWeek).shiftType,
|
||||
)
|
||||
"
|
||||
>
|
||||
<span class="schedule-cell-time">
|
||||
{{
|
||||
props.getShiftTimeText(resolveDayShift(row, day.dayOfWeek))
|
||||
}}
|
||||
</span>
|
||||
<span class="schedule-cell-label">
|
||||
{{
|
||||
props.getShiftLabel(
|
||||
resolveDayShift(row, day.dayOfWeek).shiftType,
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Card>
|
||||
</template>
|
||||
Reference in New Issue
Block a user