fix: merge nav into single toolbar for both views, hide FC headerToolbar
- Remove FC headerToolbar and its customButtons (prev/today/next/createClazz) - Add calendar navigation (navGoPrev/Today/Next) reading FC api - Unified .view-toolbar with nav + range for both calendar and matrix - calendarDateRange ref updated in datesSet, weekRange computed dispatches per view - Remove dead FC button CSS Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+78
-117
@@ -1,6 +1,14 @@
|
||||
<template>
|
||||
<div class="clazz-page">
|
||||
<div class="view-toolbar" :class="{ 'view-toolbar--landscape': isLandscape }">
|
||||
<div class="view-toolbar__main">
|
||||
<div class="view-toolbar__nav">
|
||||
<van-button size="small" @click="navGoPrev">‹</van-button>
|
||||
<van-button size="small" @click="navGoToday">本周</van-button>
|
||||
<van-button size="small" @click="navGoNext">›</van-button>
|
||||
</div>
|
||||
<span class="view-toolbar__range">{{ weekRange }}</span>
|
||||
</div>
|
||||
<div class="view-toolbar__actions">
|
||||
<div v-if="viewMode === 'matrix'" class="view-toolbar__orient">
|
||||
<van-button size="small" plain @click="isLandscape = !isLandscape">
|
||||
@@ -80,16 +88,7 @@
|
||||
<FullCalendar ref="calendar" :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="viewMode === 'matrix'" class="matrix-page">
|
||||
<div class="matrix-toolbar">
|
||||
<div class="matrix-toolbar__nav">
|
||||
<van-button size="small" @click="matrixGoPrev">‹</van-button>
|
||||
<van-button size="small" @click="matrixGoToday">本周</van-button>
|
||||
<van-button size="small" @click="matrixGoNext">›</van-button>
|
||||
</div>
|
||||
<span class="matrix-toolbar__range">{{ matrixWeekRange }}</span>
|
||||
</div>
|
||||
<div class="matrix-container">
|
||||
<div v-show="viewMode === 'matrix'" class="matrix-container">
|
||||
<div v-if="teacherList.length > 1" class="matrix-teacher-filter">
|
||||
<van-tag
|
||||
:color="selectedTeacherIds.length === 0 ? '#1989fa' : '#e8e8e8'"
|
||||
@@ -112,7 +111,6 @@
|
||||
@event-click="onMatrixEventClick"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-subsidiary" ref="footer" v-if="subsidiaries.length > 0">
|
||||
<van-tag type="primary" :color="isTagPlain(item) ? 'rgba(204, 204, 204, 0.5)' : item.color" :text-color="isTagPlain(item) ? item.color : '#333'" @click="toggleTeacherView(item.to_user_id)" v-for="item in subsidiaries">{{ item.to_user_realname }}</van-tag>
|
||||
</div>
|
||||
@@ -425,6 +423,31 @@ export default defineComponent({
|
||||
});
|
||||
const matrixWeekRange = computed(() => `${matrixWeekStart.value} ~ ${matrixWeekEnd.value}`);
|
||||
|
||||
// 日历视图日期范围(由 datesSet 更新)
|
||||
const calendarDateRange = ref('');
|
||||
|
||||
// 统一切换:矩阵用 matrixWeekRange,日历时用 calendarDateRange
|
||||
const weekRange = computed(() =>
|
||||
viewMode.value === 'matrix' ? matrixWeekRange.value : calendarDateRange.value
|
||||
);
|
||||
|
||||
// 导航按钮分发(日历 / 矩阵)
|
||||
const navGoPrev = () => {
|
||||
if (viewMode.value === 'matrix') return matrixGoPrev();
|
||||
const api = calendar.value?.getApi?.();
|
||||
api?.prev();
|
||||
// datesSet 会自动更新 calendarDateRange
|
||||
};
|
||||
const navGoToday = () => {
|
||||
if (viewMode.value === 'matrix') return matrixGoToday();
|
||||
calendar.value?.getApi?.().gotoDate(new Date());
|
||||
};
|
||||
const navGoNext = () => {
|
||||
if (viewMode.value === 'matrix') return matrixGoNext();
|
||||
const api = calendar.value?.getApi?.();
|
||||
api?.next();
|
||||
};
|
||||
|
||||
// 标准化事件模型(供矩阵视图消费)
|
||||
const {normalizedEvents} = useClazzViewModel({
|
||||
list: computed(() => store.list),
|
||||
@@ -749,32 +772,7 @@ export default defineComponent({
|
||||
const options: CalendarOptions = {
|
||||
locale: zhLocale,
|
||||
// themeSystem: 'bootstrap5',
|
||||
customButtons: {
|
||||
current: {
|
||||
text: '本周',
|
||||
click: function() {
|
||||
calendar.value.getApi().gotoDate(new Date())
|
||||
}
|
||||
},
|
||||
createClazz: {
|
||||
text: '创建排课',
|
||||
click: function() {
|
||||
if (!is_teacher.value) return;
|
||||
const now = new Date();
|
||||
store.current.start_from = formatDate(now, DateFormatter.DateTimeSave);
|
||||
now.setMinutes(now.getMinutes() + 45);
|
||||
store.current.end_by = formatDate(now, DateFormatter.DateTimeSave);
|
||||
state.editing = true;
|
||||
state.readonly = false;
|
||||
state.title = "新增排课"
|
||||
}
|
||||
}
|
||||
},
|
||||
headerToolbar: {
|
||||
left: 'prev,current,next',
|
||||
center: 'title',
|
||||
right: 'createClazz'
|
||||
},
|
||||
headerToolbar: false,
|
||||
plugins: [ dayGridPlugin, bootstrap5Plugin, timeGridPlugin, interactionPlugin ],
|
||||
initialView: 'timeGridWeek',
|
||||
initialDate: initialDate,
|
||||
@@ -817,6 +815,10 @@ export default defineComponent({
|
||||
datesSet: function({start, end}) {
|
||||
// 矩阵视图有自己的日期范围和数据加载逻辑
|
||||
if (viewMode.value === 'matrix') return;
|
||||
// 更新日历日期范围显示
|
||||
const endDate = new Date(end);
|
||||
endDate.setDate(endDate.getDate() - 1);
|
||||
calendarDateRange.value = `${formatDate(start, DateFormatter.Date)} ~ ${formatDate(endDate, DateFormatter.Date)}`;
|
||||
if (store.hanging) {
|
||||
store.hanging = false;
|
||||
let {state: cachedState} = getKey('clazz_state');
|
||||
@@ -1088,6 +1090,7 @@ export default defineComponent({
|
||||
isLandscape, matrixWeekStart, matrixWeekEnd, matrixWeekRange, matrixWeekDays,
|
||||
matrixGoPrev, matrixGoNext, matrixGoToday,
|
||||
onMatrixCellClick, onMatrixEventClick,
|
||||
weekRange, calendarDateRange, navGoPrev, navGoToday, navGoNext,
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -1103,10 +1106,6 @@ export default defineComponent({
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
|
||||
:deep(.fc-toolbar-title) {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
:deep(.fc) {
|
||||
height: 100%;
|
||||
}
|
||||
@@ -1116,35 +1115,6 @@ export default defineComponent({
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
// FullCalendar 按钮统一为白底描线,与矩阵视图一致
|
||||
:deep(.fc .fc-button-primary) {
|
||||
background: #fff;
|
||||
border: 1px solid #c8c9cc;
|
||||
color: #333;
|
||||
font-size: 0.24rem;
|
||||
height: 0.5rem;
|
||||
padding: 0 0.15rem;
|
||||
border-radius: 0.06rem;
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover { background: #f7f8fa; }
|
||||
&:active { background: #e8e8e8; }
|
||||
&:focus { box-shadow: none; }
|
||||
}
|
||||
|
||||
:deep(.fc .fc-button-primary:disabled) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
:deep(.fc .fc-button-primary.fc-button-active) {
|
||||
background: #1989fa;
|
||||
border-color: #1989fa;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.calendar-wrapper {
|
||||
@@ -1364,7 +1334,9 @@ export default defineComponent({
|
||||
.view-toolbar {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.08rem;
|
||||
padding: 0.08rem 0.12rem;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
@@ -1373,12 +1345,46 @@ export default defineComponent({
|
||||
display: none;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
&__main {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.08rem;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.08rem;
|
||||
}
|
||||
|
||||
&__range {
|
||||
min-width: 0;
|
||||
font-size: 0.2rem;
|
||||
color: #666;
|
||||
line-height: 1.3;
|
||||
white-space: normal;
|
||||
overflow: visible;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
&__nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.08rem;
|
||||
|
||||
.van-button--small {
|
||||
height: 0.5rem;
|
||||
min-width: 0.62rem;
|
||||
padding: 0 0.15rem;
|
||||
font-size: 0.24rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
&__orient {
|
||||
.van-button--small {
|
||||
height: 0.5rem;
|
||||
@@ -1408,51 +1414,6 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
/* ═══ 矩阵视图内置工具栏(与日历 FC headerToolbar 对齐) ═══ */
|
||||
.matrix-page {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.matrix-toolbar {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.08rem;
|
||||
padding: 0.08rem 0.12rem;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
|
||||
&__nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.08rem;
|
||||
|
||||
.van-button--small {
|
||||
height: 0.5rem;
|
||||
min-width: 0.62rem;
|
||||
padding: 0 0.15rem;
|
||||
font-size: 0.24rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
&__range {
|
||||
min-width: 0;
|
||||
font-size: 0.2rem;
|
||||
color: #666;
|
||||
line-height: 1.3;
|
||||
white-space: normal;
|
||||
overflow: visible;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
|
||||
.landscape-shell {
|
||||
--landscape-toolbar-height: 0.68rem;
|
||||
--clazz-landscape-body-height: calc(100dvh - var(--landscape-toolbar-height));
|
||||
|
||||
Reference in New Issue
Block a user