瀏覽代碼

group over

wuheng 1 年之前
父節點
當前提交
7410f698a2

+ 2 - 2
src/typings/page-route.d.ts

@@ -53,10 +53,10 @@ declare namespace PageRoute {
     | 'function_tab-multi-detail'
     | 'function_tab'
     | 'lesson'
+    | 'lesson_calendar'
     | 'lesson_classroom'
     | 'lesson_group'
     | 'lesson_schedule'
-    | 'lesson_calendar'
     | 'lesson_student'
     | 'management'
     | 'management_auth'
@@ -118,10 +118,10 @@ declare namespace PageRoute {
     | 'function_tab-detail'
     | 'function_tab-multi-detail'
     | 'function_tab'
+    | 'lesson_calendar'
     | 'lesson_classroom'
     | 'lesson_group'
     | 'lesson_schedule'
-    | 'lesson_calendar'
     | 'lesson_student'
     | 'management_auth'
     | 'management_role'

+ 18 - 0
src/utils/form/date.ts

@@ -9,3 +9,21 @@ export const formatTimestamp = (timestamp: number): string => {
 
   return `${year}-${month}-${day} ${hour}:${minute}`;
 };
+
+export const formatDate = (date: Date): string => {
+  const year = date.getFullYear();
+  const month = `0${date.getMonth() + 1}`.slice(-2);
+  const day = `0${date.getDate()}`.slice(-2);
+  const hour = `0${date.getHours()}`.slice(-2);
+  const minute = `0${date.getMinutes()}`.slice(-2);
+
+  return `${year}-${month}-${day} ${hour}:${minute}`;
+};
+
+export function getLastDayOfMonth(date: Date) {
+  return new Date(date.getFullYear(), date.getMonth() + 1, 0, 23, 59, 59);
+}
+
+export function getFirstDayOfMonth(date: Date) {
+  return new Date(date.getFullYear(), date.getMonth(), 1);
+}

+ 1 - 1
src/views/index.ts

@@ -32,10 +32,10 @@ export const views: Record<
   'function_tab-detail': () => import('./function/tab-detail/index.vue'),
   'function_tab-multi-detail': () => import('./function/tab-multi-detail/index.vue'),
   function_tab: () => import('./function/tab/index.vue'),
+  lesson_calendar: () => import('./lesson/calendar/index.vue'),
   lesson_classroom: () => import('./lesson/classroom/index.vue'),
   lesson_group: () => import('./lesson/group/index.vue'),
   lesson_schedule: () => import('./lesson/schedule/index.vue'),
-  lesson_calendar: () => import('./lesson/calendar/index.vue'),
   lesson_student: () => import('./lesson/student/index.vue'),
   management_auth: () => import('./management/auth/index.vue'),
   management_role: () => import('./management/role/index.vue'),

+ 123 - 10
src/views/lesson/calendar/api.ts

@@ -1,16 +1,16 @@
 import { request } from '@/service/request';
 
 export interface QueryScheduleParams {
-  studentId?: number | null;
-  classId?: number | null;
-  subjectId?: number | null;
-  teacherId?: number | null;
-  startTime?: string | null;
-  endTime?: string | null;
-  week?: number | null;
-  roomId?: number | null;
-  assistantId?: number | null;
-  categoryId?: number | null;
+  studentId?: number | null | undefined;
+  classId?: number | null | undefined;
+  subjectId?: number | null | undefined;
+  teacherId?: number | null | undefined;
+  startTime?: string | null | undefined;
+  endTime?: string | null | undefined;
+  week?: number | null | undefined;
+  roomId?: number | null | undefined;
+  assistantId?: number | null | undefined;
+  categoryId?: number | null | undefined;
 }
 
 interface ScheduleResponse {
@@ -38,3 +38,116 @@ interface ScheduleResponse {
 export function querySchedule(params: QueryScheduleParams): Promise<Service.RequestResult<ScheduleResponse[]>> {
   return request.post(`/schedule/querySchedule`, params);
 }
+
+export interface EasSysStudentOptional {
+  id?: number;
+  studentNumber?: string;
+  studentName?: string;
+  gender?: string;
+  phone?: string;
+  email?: string;
+  enrollmentDate?: Date;
+  passwd?: string;
+  avatar?: string;
+  createTime?: Date;
+  modifyTime?: Date;
+  admissionsId?: number;
+  managerId?: number;
+  createUid?: number;
+  disabled?: string;
+}
+
+export function getStudentByKeyword(keyword: string): Promise<Service.RequestResult<EasSysStudentOptional[]>> {
+  return request.get(`/student/getStudentByKeyword?keyword=${keyword}`);
+}
+
+export interface UserParams {
+  id?: number;
+  username?: string;
+  passwd?: string;
+  email?: string;
+  relname?: string;
+  phone?: string;
+  address?: string;
+  createTime?: Record<string, unknown>;
+  modifyTime?: Record<string, unknown>;
+  createUid?: number;
+  disabled?: string;
+}
+export function queryUserAll(): Promise<Service.RequestResult<UserParams[]>> {
+  return request.get(`/userinfo/queryAll`);
+}
+
+export interface ClassRoomParams {
+  id?: number;
+  name?: string;
+  managerId?: number;
+  address?: string;
+  manager?: string;
+  floor?: number;
+  capacity?: number;
+  comment?: string;
+  disabled?: string;
+  createTime?: Record<string, unknown>;
+  modifyTime?: Record<string, unknown>;
+  createUid?: number;
+}
+
+export function queryClassRoomList(
+  pageNum: number,
+  pageSize: number,
+  params: ClassRoomParams
+): Promise<Service.RequestResult<ClassRoomParams[]>> {
+  return request.post(`/classroom/query?pageNum=${pageNum}&pageSize=${pageSize}`, params);
+}
+
+export interface CategoryParams {
+  id?: number;
+  name?: string;
+  description?: string;
+  createTime?: Record<string, unknown>;
+  modifyTime?: Record<string, unknown>;
+  createUid?: number;
+  disabled?: string;
+}
+
+/**
+ * 根据条件进行查询课程类别
+ * @param {string} pageNum
+ * @param {string} pageSize
+ * @param {object} params EasEduCategory
+ * @param {number} params.id
+ * @param {string} params.name 学科名称
+ * @param {string} params.description 学科描述
+ * @param {object} params.createTime 创建时间
+ * @param {object} params.modifyTime 修改时间
+ * @param {number} params.createUid 创建用户ID
+ * @param {string} params.disabled 状态
+ * @returns
+ */
+export function queryCategoryParams(
+  pageNum: number,
+  pageSize: number,
+  params: CategoryParams
+): Promise<Service.RequestResult<CategoryParams[]>> {
+  return request.post(`/category/query?pageNum=${pageNum}&pageSize=${pageSize}`, params);
+}
+
+export interface ClassParams {
+  id?: number;
+  name?: string;
+  manageId?: number;
+  assistantId?: number;
+  createTime?: Record<string, unknown>;
+  modifyTime?: Record<string, unknown>;
+  createUid?: number;
+  disabled?: string;
+}
+
+/**
+ * 查询所有的班级类
+ * @returns
+ */
+export function queryClassAll(): Promise<Service.RequestResult<ClassParams[]>> {
+  return request.get(`/class/selectTotal`);
+}

+ 194 - 17
src/views/lesson/calendar/index.vue

@@ -1,7 +1,46 @@
 <template>
   <div class="wh-full bg-white">
-    <div class="flex-col-center" style="width: 70%; margin: 0 auto; margin-top: 5%">
-      <n-calendar v-if="show" style="width: 100%" #="{ year, month, date }" @update:value="handleUpdateValue">
+    <n-form :label-width="200" inline>
+      <n-form-item class="min-w-34" label="请选择查询学员" path="scheduleParamsOptions.studentId">
+        <n-select
+          v-model:value="scheduleParamsOptions.studentId"
+          filterable
+          placeholder="请选择查询学员"
+          :options="studentOptions"
+          :loading="studentOptionsLoading"
+          clearable
+          remote
+          @search="studentOptionsSearch"
+        />
+      </n-form-item>
+      <n-form-item class="min-w-34" label="请选择要查询的班级" path="scheduleParamsOptions.classId">
+        <n-select
+          v-model:value="scheduleParamsOptions.classId"
+          :options="groupList"
+          clearable
+          placeholder="请选择班级"
+        />
+      </n-form-item>
+      <n-form-item class="min-w-34" label="要查询的授课教师" path="scheduleParamsOptions.teacherId">
+        <n-select
+          v-model:value="scheduleParamsOptions.teacherId"
+          :options="teacherOptions"
+          placeholder="请选择授课教师"
+          clearable
+        />
+      </n-form-item>
+      <n-form-item>
+        <n-button type="primary" @click="loadScheduleQuery"> 搜索 </n-button>
+      </n-form-item>
+    </n-form>
+    <div class="flex-col-center" style="width: 70%; margin: 0 auto; margin-top: 1%">
+      <n-calendar
+        v-if="show"
+        style="width: 100%"
+        #="{ year, month, date }"
+        @panel-change="handlePanelChange"
+        @update:value="handleUpdateValue"
+      >
         {{ year }}年{{ month }}月{{ date }}日 <br />
         <n-tag v-if="dataList[`${year}-${doubleMonth(month)}-${date}`]" type="success">
           共有课时:
@@ -36,11 +75,41 @@
 </template>
 <script setup lang="ts">
 import { ref, reactive } from 'vue';
-import { querySchedule } from './api';
+import { useRoute } from 'vue-router';
+import { formatDate, getFirstDayOfMonth, getLastDayOfMonth } from '@/utils';
+import {
+  querySchedule,
+  getStudentByKeyword,
+  queryCategoryParams,
+  queryUserAll,
+  queryClassAll,
+  queryClassRoomList
+} from './api';
+import type { QueryScheduleParams } from './api';
+const route = useRoute();
+const classId = route.query.classId;
+const studentId = route.query.studentId;
 const show = ref(false);
 const showModal = ref(false);
 const list = ref<any>([]);
-const allList = ref<any>({});
+const allList = reactive<any>({});
+const studentOptions = ref<any[]>([]);
+const studentOptionsLoading = ref<boolean>(false);
+const categoryAndSubjectOptions = ref<any[]>([]);
+const groupList = ref<any[]>([]);
+const classRoomList = ref<any[]>([]);
+const teacherOptions = ref<any[]>();
+const scheduleParamsOptions = ref<QueryScheduleParams>({
+  studentId: null,
+  classId: null,
+  subjectId: null,
+  teacherId: null,
+  startTime: formatDate(getFirstDayOfMonth(new Date())),
+  endTime: formatDate(getLastDayOfMonth(new Date())),
+  roomId: null,
+  assistantId: null,
+  categoryId: null
+});
 const dataList = reactive<{ [index: string]: any }>({});
 function handleUpdateValue(_: number, { year, month, date }: { year: number; month: number; date: number }) {
   if (dataList[`${year}-${doubleMonth(month)}-${date}`]) {
@@ -48,25 +117,133 @@ function handleUpdateValue(_: number, { year, month, date }: { year: number; mon
     showModal.value = true;
   }
 }
+async function findStudent(sId: number) {
+  if (sId) {
+    studentOptionsLoading.value = true;
+    studentOptions.value = [];
+    getStudentByKeyword(sId.toString()).then(response => {
+      response.data?.forEach(r => {
+        studentOptions.value.push({
+          label: r.studentName,
+          value: r.id
+        });
+        if (Number(sId) === r.id) {
+          scheduleParamsOptions.value.studentId = Number(sId);
+        }
+      });
+    });
+    studentOptionsLoading.value = false;
+    loadScheduleQuery();
+  }
+}
+function studentOptionsSearch(keyword: string) {
+  if (!keyword.length) {
+    studentOptions.value = [];
+    return;
+  }
+  studentOptionsLoading.value = true;
+  studentOptions.value = [];
+  getStudentByKeyword(keyword).then(response => {
+    response.data?.forEach(r => {
+      studentOptions.value.push({
+        label: r.studentName,
+        value: r.id
+      });
+    });
+  });
+  studentOptionsLoading.value = false;
+}
 function doubleMonth(month: number) {
   return month < 10 ? `0${month}` : month;
 }
-querySchedule({}).then(response => {
-  response.data?.forEach(result => {
-    if (result.createTime) {
-      const key = result.createTime.split(' ')[0].toString();
-      if (!allList[key]) {
-        allList[key] = [];
+
+function handlePanelChange(event: { year: number; month: number }) {
+  scheduleParamsOptions.value.startTime = formatDate(getFirstDayOfMonth(new Date(event.year, event.month - 1)));
+  scheduleParamsOptions.value.endTime = formatDate(getLastDayOfMonth(new Date(event.year, event.month - 1)));
+  loadScheduleQuery();
+}
+
+async function loadData() {
+  await queryUserAll().then(response => {
+    teacherOptions.value = response.data?.map(r => {
+      return {
+        label: r.relname,
+        value: r.id
+      };
+    });
+  });
+  await queryCategoryParams(1, 100, {}).then(response => {
+    response.data?.map(r => {
+      categoryAndSubjectOptions.value.push({
+        label: r.name,
+        value: r.id,
+        depth: 1,
+        isLeaf: false
+      });
+      return r;
+    });
+  });
+  await queryClassAll().then(response => {
+    response.data?.map(r => {
+      groupList.value.push({
+        label: r.name,
+        value: r.id
+      });
+      if (Number(classId) === r.id) {
+        scheduleParamsOptions.value.classId = Number(classId);
+      }
+      return r;
+    });
+  });
+  await queryClassRoomList(1, 100, {}).then(response => {
+    response.data?.map(r => {
+      classRoomList.value.push({
+        label: r.name,
+        value: r.id
+      });
+      return r;
+    });
+  });
+
+  await findStudent(Number(studentId));
+
+  loadScheduleQuery();
+}
+
+function loadScheduleQuery() {
+  querySchedule(scheduleParamsOptions.value).then(response => {
+    if (dataList) {
+      for (const key in dataList) {
+        if (dataList[key]) {
+          delete dataList[key];
+        }
       }
-      allList[key].push(result);
-      if (dataList[key]) {
-        dataList[key] += dataList[key];
-      } else {
-        dataList[key] = 1;
+    }
+    if (allList) {
+      for (const key in allList) {
+        if (allList[key]) {
+          delete allList[key];
+        }
       }
     }
+    list.value = [];
+    response.data?.forEach(result => {
+      if (result.createTime) {
+        const key = result.createTime.split(' ')[0].toString();
+        if (!allList[key]) {
+          allList[key] = [];
+        }
+        allList[key].push(result);
+        if (dataList[key]) {
+          dataList[key] += dataList[key];
+        } else {
+          dataList[key] = 1;
+        }
+      }
+    });
+    show.value = true;
   });
-  show.value = true;
-});
+}
+loadData();
 </script>
 <style scoped></style>

+ 16 - 0
src/views/lesson/group/crud.ts

@@ -13,6 +13,7 @@ const dictOpt = {
 function curd({ context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
   const openModel = context?.openModel;
   const goToSchedule = context?.goToSchedule;
+  const goToCalendar = context?.goToCalendar;
   return {
     crudOptions: {
       request: {
@@ -204,6 +205,21 @@ function curd({ context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
             click: ({ row }) => {
               goToSchedule(row.id);
             }
+          },
+          calendar: {
+            text: null,
+            size: 'small',
+            icon: 'ph:calendar-fill',
+            tooltip: {
+              slots: {
+                default() {
+                  return '查看排课日历';
+                }
+              }
+            },
+            click: ({ row }) => {
+              goToCalendar(row.id);
+            }
           }
         }
       }

+ 8 - 0
src/views/lesson/group/index.vue

@@ -52,6 +52,14 @@ const context: any = {
       };
     });
     pageType.value = true;
+  },
+  goToCalendar: (classId: number) => {
+    router.push({
+      path: '/lesson/calendar',
+      query: {
+        classId
+      }
+    });
   }
 };
 const { crudRef, crudBinding, crudExpose } = useFs({ createCrudOptions, context });