|
@@ -1,11 +1,11 @@
|
|
|
<template>
|
|
|
<div class="h-full bg-white">
|
|
|
<div v-if="pageState" style="margin-top: 1rem">
|
|
|
- <n-form inline>
|
|
|
- <n-form-item label="请选择查询学员" path="user.name">
|
|
|
+ <n-form :label-width="200" inline>
|
|
|
+ <n-form-item class="min-w-34" label="请选择查询学员" path="user.name">
|
|
|
<n-input placeholder="请选择查询学员" />
|
|
|
</n-form-item>
|
|
|
- <n-form-item label="请选择要查询的班级" path="classId">
|
|
|
+ <n-form-item class="min-w-34" label="请选择要查询的班级" path="classId">
|
|
|
<n-select
|
|
|
v-model:value="scheduleParamsOptions.classId"
|
|
|
:options="groupList"
|
|
@@ -13,7 +13,7 @@
|
|
|
placeholder="请选择班级"
|
|
|
/>
|
|
|
</n-form-item>
|
|
|
- <n-form-item label="请选择要查询的时间范围" path="user.name">
|
|
|
+ <n-form-item class="min-w-34" label="请选择要查询的时间范围" path="user.name">
|
|
|
<n-date-picker
|
|
|
v-model:value="dateRange"
|
|
|
type="daterange"
|
|
@@ -29,7 +29,7 @@
|
|
|
"
|
|
|
/>
|
|
|
</n-form-item>
|
|
|
- <n-form-item label="请选择要查询的授课教师" path="user.name">
|
|
|
+ <n-form-item class="min-w-34" label="要查询的授课教师" path="user.name">
|
|
|
<n-select
|
|
|
v-model:value="scheduleParamsOptions.teacherId"
|
|
|
:options="teacherOptions"
|
|
@@ -37,102 +37,113 @@
|
|
|
clearable
|
|
|
/>
|
|
|
</n-form-item>
|
|
|
- <n-form-item>
|
|
|
- <n-button-group>
|
|
|
- <n-button type="primary" ghost> 上一周 </n-button>
|
|
|
- <n-button type="primary" ghost> 下一周 </n-button>
|
|
|
- <n-button type="primary" ghost @click="loadScheduleQuery"> 搜索 </n-button>
|
|
|
- <n-button type="primary" @click="pageState = !pageState"> 新增排课 </n-button>
|
|
|
- </n-button-group>
|
|
|
- </n-form-item>
|
|
|
</n-form>
|
|
|
- <div style="width: 100%; height: 1rem"></div>
|
|
|
- <div style="width: 100%; height: 1rem"></div>
|
|
|
- <table border="1" style="width: 100%">
|
|
|
- <tbody width="100">
|
|
|
- <tr>
|
|
|
- <th>时间</th>
|
|
|
- <th>周一</th>
|
|
|
- <th>周二</th>
|
|
|
- <th>周三</th>
|
|
|
- <th>周四</th>
|
|
|
- <th>周五</th>
|
|
|
- <th>周六</th>
|
|
|
- <th>周日</th>
|
|
|
- </tr>
|
|
|
- <tr v-for="key in timeKey" :key="key">
|
|
|
- <td>{{ key }}</td>
|
|
|
- <template v-for="index in [1, 2, 3, 4, 5, 6, 7]" :key="index">
|
|
|
- <td
|
|
|
- v-if="
|
|
|
- scheduleList[index][key] &&
|
|
|
- scheduleList[index][key]['empty'] === false &&
|
|
|
- scheduleList[index][key]['break'] === false
|
|
|
- "
|
|
|
- :rowspan="scheduleList[index][key]['colspan']"
|
|
|
- >
|
|
|
- {{ scheduleList[index][key]['startTime'] }} <br />
|
|
|
- {{ scheduleList[index][key]['endTime'] }}
|
|
|
- </td>
|
|
|
- <td v-else-if="scheduleList[index][key] && scheduleList[index][key]['empty'] === true">暂无</td>
|
|
|
- </template>
|
|
|
- </tr>
|
|
|
- </tbody>
|
|
|
- </table>
|
|
|
+ <n-button-group>
|
|
|
+ <n-button type="primary" ghost @click="previousDateSchedule"> 上一周 </n-button>
|
|
|
+ <n-button type="primary" ghost @click="nextDateSchedule"> 下一周 </n-button>
|
|
|
+ <n-button type="primary" @click="loadScheduleQuery"> 搜索 </n-button>
|
|
|
+ <n-button type="primary" @click="pageState = !pageState"> 新增排课 </n-button>
|
|
|
+ </n-button-group>
|
|
|
+ <div style="height: 1rem"></div>
|
|
|
+ <n-spin :show="loading">
|
|
|
+ <table border="1" style="width: 100%">
|
|
|
+ <tbody width="100">
|
|
|
+ <tr>
|
|
|
+ <th class="w-20 color-blue-800">时间</th>
|
|
|
+ <th v-for="weekDate in [0, 1, 2, 3, 4, 5, 6]" :key="weekDate" class="font-500 color-blue-800">
|
|
|
+ {{ new Date(weekStartTime + weekDate * 86400000).getMonth() + 1 }}月{{
|
|
|
+ new Date(weekStartTime + weekDate * 86400000).getDate()
|
|
|
+ }}号 - 周{{ chineseNumbers[getDayOfTheWeekNow(weekStartTime - 1, weekDate)] }}
|
|
|
+ </th>
|
|
|
+ </tr>
|
|
|
+ <tr v-for="key in timeKey" :key="key">
|
|
|
+ <td>{{ key }}</td>
|
|
|
+ <template v-for="index in [0, 1, 2, 3, 4, 5, 6]" :key="index">
|
|
|
+ <td
|
|
|
+ v-if="
|
|
|
+ scheduleList[getDayOfTheWeekNow(weekStartTime, index)][key] &&
|
|
|
+ scheduleList[getDayOfTheWeekNow(weekStartTime, index)][key]['empty'] === false &&
|
|
|
+ scheduleList[getDayOfTheWeekNow(weekStartTime, index)][key]['break'] === false
|
|
|
+ "
|
|
|
+ :rowspan="scheduleList[getDayOfTheWeekNow(weekStartTime, index)][key]['colspan']"
|
|
|
+ >
|
|
|
+ {{ scheduleList[getDayOfTheWeekNow(weekStartTime, index)][key]['startTime'] }} <br />
|
|
|
+ {{ scheduleList[getDayOfTheWeekNow(weekStartTime, index)][key]['endTime'] }}
|
|
|
+ </td>
|
|
|
+ <td
|
|
|
+ v-else-if="
|
|
|
+ scheduleList[getDayOfTheWeekNow(weekStartTime, index)][key] &&
|
|
|
+ scheduleList[getDayOfTheWeekNow(weekStartTime, index)][key]['empty'] === true
|
|
|
+ "
|
|
|
+ >
|
|
|
+ 暂无
|
|
|
+ </td>
|
|
|
+ </template>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </n-spin>
|
|
|
</div>
|
|
|
<div v-if="!pageState" class="wh-full flex-col-center">
|
|
|
- <n-form ref="formRef" size="large" label-placement="left" style="margin-right: 5rem" :model="model">
|
|
|
- <n-form-item label="排课班级" path="groupList">
|
|
|
- <n-select v-model:value="model.classId" :options="groupList" />
|
|
|
- </n-form-item>
|
|
|
- <n-form-item label="所在教室" path="classRoomList">
|
|
|
- <n-select v-model:value="model.roomId" :options="classRoomList" />
|
|
|
- </n-form-item>
|
|
|
- <n-form-item label="任课老师" path="teacherId">
|
|
|
- <n-select v-model:value="model.teacherId" placeholder="请选择任课老师" :options="teacherOptions" clearable />
|
|
|
- </n-form-item>
|
|
|
- <n-form-item label="助教老师" path="multipleSelectValue">
|
|
|
- <n-select
|
|
|
- v-model:value="model.assistantId"
|
|
|
- placeholder="请选择助教老师"
|
|
|
- :options="teacherOptions"
|
|
|
- clearable
|
|
|
- />
|
|
|
- </n-form-item>
|
|
|
- <n-form-item label="教授科目" path="multipleSelectValue">
|
|
|
- <n-cascader
|
|
|
- v-model:value="model.subjectsId"
|
|
|
- placeholder="请选择课程"
|
|
|
- :options="categoryAndSubjectOptions"
|
|
|
- show-path
|
|
|
- check-strategy="child"
|
|
|
- remote
|
|
|
- :on-load="categoryAndSubjectLoad"
|
|
|
- />
|
|
|
- </n-form-item>
|
|
|
- <n-form-item label="上课时间" path="datetimeValue">
|
|
|
- <n-space>
|
|
|
- <n-date-picker v-model:value="dateValue" time-zone="Asia/Shanghai" type="date" />
|
|
|
- <n-time-picker v-model:value="startTime" time-zone="Asia/Shanghai" />
|
|
|
- <n-time-picker v-model:value="endTime" time-zone="Asia/Shanghai" />
|
|
|
- </n-space>
|
|
|
- </n-form-item>
|
|
|
- <n-form-item label="是否连选" path="switchValue">
|
|
|
- <n-switch v-model:value="isRepeatTime" />
|
|
|
- </n-form-item>
|
|
|
- <n-form-item label="连选天数" path="sliderValue">
|
|
|
- <n-slider v-model:value="repeatTime" :step="1" :max="7" />
|
|
|
- </n-form-item>
|
|
|
- <n-form-item label="单节课时长" path="inputNumberValue">
|
|
|
- <n-input-number v-model:value="model.lessonTime" />
|
|
|
- </n-form-item>
|
|
|
- <div style="display: flex; justify-content: flex-end">
|
|
|
- <n-button-group>
|
|
|
- <n-button type="primary" @click="handleValidateButtonClick"> 确认提交 </n-button>
|
|
|
- <n-button type="primary" @click="pageState = !pageState"> 返回前一页 </n-button>
|
|
|
- </n-button-group>
|
|
|
- </div>
|
|
|
- </n-form>
|
|
|
+ <n-spin :show="formLoading">
|
|
|
+ <n-form ref="formRef" size="large" label-placement="left" style="margin-right: 5rem" :model="model">
|
|
|
+ <n-form-item label="排课班级" path="groupList">
|
|
|
+ <n-select v-model:value="model.classId" :options="groupList" />
|
|
|
+ </n-form-item>
|
|
|
+ <n-form-item label="所在教室" path="classRoomList">
|
|
|
+ <n-select v-model:value="model.roomId" :options="classRoomList" />
|
|
|
+ </n-form-item>
|
|
|
+ <n-form-item label="任课老师" path="teacherId">
|
|
|
+ <n-select
|
|
|
+ v-model:value="model.teacherId"
|
|
|
+ placeholder="请选择任课老师"
|
|
|
+ :options="teacherOptions"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </n-form-item>
|
|
|
+ <n-form-item label="助教老师" path="multipleSelectValue">
|
|
|
+ <n-select
|
|
|
+ v-model:value="model.assistantId"
|
|
|
+ placeholder="请选择助教老师"
|
|
|
+ :options="teacherOptions"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </n-form-item>
|
|
|
+ <n-form-item label="教授科目" path="multipleSelectValue">
|
|
|
+ <n-cascader
|
|
|
+ v-model:value="model.subjectsId"
|
|
|
+ placeholder="请选择课程"
|
|
|
+ :options="categoryAndSubjectOptions"
|
|
|
+ show-path
|
|
|
+ check-strategy="child"
|
|
|
+ remote
|
|
|
+ :on-load="categoryAndSubjectLoad"
|
|
|
+ />
|
|
|
+ </n-form-item>
|
|
|
+ <n-form-item label="上课时间" path="datetimeValue">
|
|
|
+ <n-space>
|
|
|
+ <n-date-picker v-model:value="dateValue" clearable time-zone="Asia/Shanghai" type="date" />
|
|
|
+ <n-time-picker v-model:value="startTime" clearable time-zone="Asia/Shanghai" />
|
|
|
+ <n-time-picker v-model:value="endTime" clearable time-zone="Asia/Shanghai" />
|
|
|
+ </n-space>
|
|
|
+ </n-form-item>
|
|
|
+ <n-form-item label="是否连选" path="switchValue">
|
|
|
+ <n-switch v-model:value="isRepeatTime" />
|
|
|
+ </n-form-item>
|
|
|
+ <n-form-item label="连选天数" path="sliderValue">
|
|
|
+ <n-slider v-model:value="repeatTime" :step="1" :max="7" />
|
|
|
+ </n-form-item>
|
|
|
+ <n-form-item label="单节课时长" path="inputNumberValue">
|
|
|
+ <n-input-number v-model:value="model.lessonTime" />
|
|
|
+ </n-form-item>
|
|
|
+ <div style="display: flex; justify-content: flex-end">
|
|
|
+ <n-button-group>
|
|
|
+ <n-button type="primary" @click="handleValidateButtonClick"> 确认提交 </n-button>
|
|
|
+ <n-button type="primary" @click="pageState = !pageState"> 返回前一页 </n-button>
|
|
|
+ </n-button-group>
|
|
|
+ </div>
|
|
|
+ </n-form>
|
|
|
+ </n-spin>
|
|
|
</div>
|
|
|
<div style="width: 100%; height: 1rem"></div>
|
|
|
</div>
|
|
@@ -169,6 +180,18 @@ const model = reactive<ScheduleParams>({
|
|
|
disabled: 'N'
|
|
|
});
|
|
|
const classId = route.query.classId;
|
|
|
+const chineseNumbers: { [index: number]: string } = {
|
|
|
+ 0: '零',
|
|
|
+ 1: '一',
|
|
|
+ 2: '二',
|
|
|
+ 3: '三',
|
|
|
+ 4: '四',
|
|
|
+ 5: '五',
|
|
|
+ 6: '六',
|
|
|
+ 7: '日',
|
|
|
+ 8: '八',
|
|
|
+ 9: '九'
|
|
|
+};
|
|
|
const dateValue = ref<number>(0);
|
|
|
const startTime = ref<number>(0);
|
|
|
const endTime = ref<number>(0);
|
|
@@ -178,8 +201,16 @@ const pageState = ref<boolean>(true);
|
|
|
const categoryAndSubjectOptions = ref<any[]>([]);
|
|
|
const groupList = ref<any[]>([]);
|
|
|
const classRoomList = ref<any[]>([]);
|
|
|
-const teacherOptions = ref();
|
|
|
-const dateRange = ref<[number, number]>([new Date().getTime(), new Date().getTime() + 86400000]);
|
|
|
+const teacherOptions = ref<any[]>();
|
|
|
+const loading = ref<boolean>(false);
|
|
|
+const formLoading = ref<boolean>(false);
|
|
|
+const nowDate = new Date();
|
|
|
+nowDate.setHours(0, 0, 0, 0);
|
|
|
+const sevenDaysLater = new Date(nowDate);
|
|
|
+sevenDaysLater.setDate(nowDate.getDate() + 6);
|
|
|
+sevenDaysLater.setHours(0, 0, 0, 0);
|
|
|
+const dateRange = ref<[number, number]>([nowDate.getTime(), sevenDaysLater.getTime()]);
|
|
|
+const weekStartTime = ref<number>(nowDate.getTime());
|
|
|
const scheduleParamsOptions = reactive<ScheduleParamsList>({
|
|
|
startTime: '',
|
|
|
endTime: '',
|
|
@@ -241,40 +272,87 @@ function categoryAndSubjectLoad(option: CascaderOption) {
|
|
|
}
|
|
|
|
|
|
async function handleValidateButtonClick() {
|
|
|
- model.startTime = formatTimestamp(dateValue.value + startTime.value);
|
|
|
- model.endTime = formatTimestamp(dateValue.value + endTime.value);
|
|
|
- model.week = new Date(dateValue.value + startTime.value).getDay() + 1;
|
|
|
+ formLoading.value = true;
|
|
|
+ const modelStartTime = new Date(startTime.value);
|
|
|
+ const modelEndTime = new Date(endTime.value);
|
|
|
+ if (modelStartTime >= modelEndTime) {
|
|
|
+ window.$message?.error('开始时间不能大于或等于结束时间');
|
|
|
+ formLoading.value = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const modelDate = new Date(dateValue.value);
|
|
|
+ modelStartTime.setFullYear(modelDate.getFullYear(), modelDate.getMonth(), modelDate.getDate());
|
|
|
+ modelEndTime.setFullYear(modelDate.getFullYear(), modelDate.getMonth(), modelDate.getDate());
|
|
|
+ model.startTime = formatTimestamp(modelStartTime.getTime());
|
|
|
+ model.endTime = formatTimestamp(modelEndTime.getTime());
|
|
|
+ model.week = modelStartTime.getDay();
|
|
|
+
|
|
|
const res = await addSchedule(repeatTime.value, model);
|
|
|
+ formLoading.value = false;
|
|
|
if (!res.status && res.msg !== null) {
|
|
|
- return window.$message?.error(res.msg);
|
|
|
+ window.$message?.error(res.msg);
|
|
|
+ return;
|
|
|
}
|
|
|
pageState.value = !pageState.value;
|
|
|
- return window.$message?.success('操作成功!');
|
|
|
+ loadScheduleQuery();
|
|
|
+ window.$message?.success('操作成功!');
|
|
|
}
|
|
|
|
|
|
-function differenceInSevenDays(nowtime: number | [number, number] | null) {
|
|
|
+function validateDate(nowtime: [number, number]): boolean {
|
|
|
if (!nowtime) {
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
if (nowtime instanceof Array) {
|
|
|
- const differenceInMilliseconds: number = nowtime[1] - nowtime[0] + 86400000;
|
|
|
+ const differenceInMilliseconds: number = nowtime[1] + 86400000 - nowtime[0];
|
|
|
const days = Math.floor(differenceInMilliseconds / (1000 * 60 * 60 * 24));
|
|
|
if (days > 7) {
|
|
|
- scheduleParamsOptions.startTime = '';
|
|
|
- scheduleParamsOptions.endTime = '';
|
|
|
- window.$message?.error('查询时间范围不能超过7天');
|
|
|
- } else {
|
|
|
- scheduleParamsOptions.startTime = formatTimestamp(Number(nowtime[1]));
|
|
|
- scheduleParamsOptions.endTime = formatTimestamp(Number(nowtime[0] + 86400000));
|
|
|
+ return false;
|
|
|
}
|
|
|
+ return true;
|
|
|
}
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+function previousDateSchedule() {
|
|
|
+ const startDateTime = new Date(dateRange.value[0] - 1);
|
|
|
+ startDateTime.setHours(0, 0, 0, 0);
|
|
|
+ const sevenDays = new Date(startDateTime);
|
|
|
+ sevenDays.setDate(startDateTime.getDate() - 6);
|
|
|
+ sevenDays.setHours(0, 0, 0, 0);
|
|
|
+ dateRange.value = [sevenDays.getTime(), startDateTime.getTime()];
|
|
|
+ loadScheduleQuery();
|
|
|
+}
|
|
|
+function nextDateSchedule() {
|
|
|
+ const endDateTime = new Date(dateRange.value[1]);
|
|
|
+ endDateTime.setHours(24, 0, 0, 0);
|
|
|
+ const sevenDays = new Date(endDateTime);
|
|
|
+ sevenDays.setDate(endDateTime.getDate() + 6);
|
|
|
+ sevenDays.setHours(0, 0, 0, 0);
|
|
|
+ dateRange.value = [endDateTime.getTime(), sevenDays.getTime()];
|
|
|
+ loadScheduleQuery();
|
|
|
+}
|
|
|
+
|
|
|
+function differenceInSevenDays(nowtime: [number, number]): boolean {
|
|
|
+ if (!validateDate(nowtime)) {
|
|
|
+ scheduleParamsOptions.startTime = '';
|
|
|
+ scheduleParamsOptions.endTime = '';
|
|
|
+ window.$message?.error('查询时间范围不能超过7天');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ scheduleParamsOptions.startTime = formatTimestamp(Number(nowtime[0]));
|
|
|
+ scheduleParamsOptions.endTime = formatTimestamp(Number(nowtime[1] + 86400000));
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
function loadScheduleQuery() {
|
|
|
- loadSchedule();
|
|
|
+ if (differenceInSevenDays(dateRange.value)) {
|
|
|
+ loadSchedule();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
function loadSchedule() {
|
|
|
+ loading.value = true;
|
|
|
querySchedule(1, 100, scheduleParamsOptions).then(response => {
|
|
|
scheduleList.value = [];
|
|
|
for (let i = 1; i <= 7; i += 1) {
|
|
@@ -283,9 +361,11 @@ function loadSchedule() {
|
|
|
scheduleList.value[i][timeKey.value[j]] = { empty: true, break: false };
|
|
|
}
|
|
|
}
|
|
|
- response.data?.data.forEach(r => {
|
|
|
+ response.data?.forEach((r: any) => {
|
|
|
+ if (!r.startTime) return;
|
|
|
const time = r.startTime?.split(' ').pop();
|
|
|
- const week = r.week;
|
|
|
+ const week = new Date(r.startTime).getDay() + 1;
|
|
|
+ if (time && timeKey.value.indexOf(time) === -1) return;
|
|
|
if (week && time && r.endTime && r.startTime && scheduleList.value[week][time].empty) {
|
|
|
r.colspan = new Date(r.endTime).getHours() - new Date(r.startTime).getHours() + 1;
|
|
|
r.empty = false;
|
|
@@ -299,9 +379,13 @@ function loadSchedule() {
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
+ weekStartTime.value = dateRange.value[0];
|
|
|
+ loading.value = false;
|
|
|
});
|
|
|
}
|
|
|
-
|
|
|
+function getDayOfTheWeekNow(theWeekStartTime: number, weekDate: number): number {
|
|
|
+ return new Date(theWeekStartTime + weekDate * 86400000).getDay() + 1;
|
|
|
+}
|
|
|
function loadData() {
|
|
|
queryUserAll().then(response => {
|
|
|
teacherOptions.value = response.data?.map(r => {
|
|
@@ -343,15 +427,17 @@ function loadData() {
|
|
|
model.classId = Number(classId);
|
|
|
}
|
|
|
});
|
|
|
- loadSchedule();
|
|
|
+ loadScheduleQuery();
|
|
|
}
|
|
|
|
|
|
loadData();
|
|
|
</script>
|
|
|
<style scoped>
|
|
|
+table {
|
|
|
+ table-layout: fixed;
|
|
|
+}
|
|
|
th {
|
|
|
- color: rgb(141, 141, 141);
|
|
|
- font-size: calc(var(--baseSize, 14px) * 1.1);
|
|
|
+ font-size: calc(var(--baseSize, 14px) * 2);
|
|
|
font-weight: bold;
|
|
|
}
|
|
|
|
|
@@ -361,6 +447,8 @@ td {
|
|
|
font-size: var(--baseSize, 14px);
|
|
|
outline: 1px solid rgb(226, 226, 226);
|
|
|
text-align: center;
|
|
|
+}
|
|
|
+td {
|
|
|
color: rgb(99, 99, 99);
|
|
|
}
|
|
|
</style>
|