wuheng 1 vuosi sitten
vanhempi
commit
3f78b5ce49

+ 2 - 1
src/locales/lang/en.ts

@@ -77,7 +77,8 @@ const locale: LocaleMessages<I18nType.Schema> = {
         route: 'Route',
         user: 'User',
         sort: 'category',
-        student: 'Student'
+        student: 'Student',
+        attendance: 'student attendance'
       },
       lesson: {
         _value: 'Lesson Management',

+ 2 - 1
src/locales/lang/zh-cn.ts

@@ -77,7 +77,8 @@ const locale: LocaleMessages<I18nType.Schema> = {
         route: '路由管理',
         user: '用户管理',
         sort: '课程分类',
-        student: '学生管理'
+        student: '学生管理',
+        attendance: '学员出勤'
       },
       lesson: {
         _value: '课程管理',

+ 11 - 0
src/router/modules/management.ts

@@ -47,6 +47,17 @@ const management: AuthRoute.Route = {
         localIcon: 'academic-cap'
       }
     },
+    {
+      name: 'management_attendance',
+      path: '/management/attendance',
+      component: 'self',
+      meta: {
+        title: '学员出勤',
+        i18nTitle: 'message.routes.management.attendance',
+        requiresAuth: true,
+        icon: 'emojione:kiss-mark'
+      }
+    },
     {
       name: 'management_sort',
       path: '/management/sort',

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

@@ -53,13 +53,14 @@ declare namespace PageRoute {
     | 'function_tab-multi-detail'
     | 'function_tab'
     | 'lesson'
-    | 'lesson_checkin'
     | 'lesson_calendar'
+    | 'lesson_checkin'
     | 'lesson_classroom'
     | 'lesson_group'
     | 'lesson_schedule'
     | 'lesson_student'
     | 'management'
+    | 'management_attendance'
     | 'management_auth'
     | 'management_role'
     | 'management_route'
@@ -119,8 +120,9 @@ declare namespace PageRoute {
     | 'function_tab-detail'
     | 'function_tab-multi-detail'
     | 'function_tab'
-    | 'lesson_checkin'
     | 'lesson_calendar'
+    | 'lesson_checkin'
+    | 'management_attendance'
     | 'lesson_classroom'
     | 'lesson_group'
     | 'lesson_schedule'

+ 1 - 0
src/typings/system.d.ts

@@ -391,6 +391,7 @@ declare namespace I18nType {
         user: string;
         sort: string;
         student: string;
+        attendance: string;
       };
       lesson: {
         _value: string;

+ 2 - 1
src/views/index.ts

@@ -32,12 +32,13 @@ 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_checkin: () => import('./lesson/checkin/index.vue'),
   lesson_calendar: () => import('./lesson/calendar/index.vue'),
+  lesson_checkin: () => import('./lesson/checkin/index.vue'),
   lesson_classroom: () => import('./lesson/classroom/index.vue'),
   lesson_group: () => import('./lesson/group/index.vue'),
   lesson_schedule: () => import('./lesson/schedule/index.vue'),
   lesson_student: () => import('./lesson/student/index.vue'),
+  management_attendance: () => import('./management/attendance/index.vue'),
   management_auth: () => import('./management/auth/index.vue'),
   management_role: () => import('./management/role/index.vue'),
   management_route: () => import('./management/route/index.vue'),

+ 29 - 2
src/views/lesson/checkin/api.ts

@@ -47,11 +47,38 @@ export function updateAttendance(params: AttendanceParams): Promise<Service.Requ
   return request.put(`/attendance/update`, params);
 }
 
+export interface GetAttendanceListParams {
+  id?: number;
+  studentId?: number;
+  month?: number;
+  startTime?: string;
+  endTime?: string;
+  teacherId?: number;
+  classId?: number;
+}
 /**
  * 获取学生列表
  * @param {string} scheduleId
  * @returns
  */
-export function getStudentList(scheduleId: number): Promise<Service.RequestResult<AttendanceParams[]>> {
-  return request.get(`/attendance/getStudentList?scheduleId=${scheduleId}`);
+export function getStudentList(params: GetAttendanceListParams) {
+  return request.post(`/attendance/getStudentList`, params);
+}
+
+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 async function queryAll(): Promise<Service.RequestResult<UserParams[]>> {
+  return request.get(`/userinfo/queryAll`);
 }

+ 55 - 20
src/views/lesson/checkin/crud.ts

@@ -1,6 +1,6 @@
 import type { CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud';
 import { dict } from '@fast-crud/fast-crud';
-import { addAttendance, updateAttendance, getStudentList } from './api';
+import { updateAttendance, getStudentList } from './api';
 
 function curd({ context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
   return {
@@ -12,14 +12,18 @@ function curd({ context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
         show: false
       },
       request: {
-        pageRequest: async ({ page }) => {
-          const { data } = await getStudentList(context?.route.query.scheduleId ?? 0);
+        pageRequest: async ({ page, query }) => {
+          const queryBody = {
+            id: context?.route.query.scheduleId ?? 9999999
+          };
+          const { data } = await getStudentList(Object.assign(queryBody, query));
           return { records: data, total: 0, currentPage: page.offset, pageSize: page.limit };
         },
-        addRequest: ({ form }) => {
-          return addAttendance(form);
+        addRequest: () => {
+          return Promise.resolve();
         },
         editRequest: ({ form }) => {
+          form.scheduleId = form.id;
           updateAttendance(form);
         }
       },
@@ -37,7 +41,23 @@ function curd({ context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
         }
       },
       columns: {
-        scheduleId: {
+        startTime: {
+          title: '上课时间',
+          type: 'easDateTime',
+          sortable: true,
+          column: {
+            width: 160
+          }
+        },
+        endTime: {
+          title: '下课时间',
+          type: 'easDateTime',
+          sortable: true,
+          column: {
+            width: 160
+          }
+        },
+        id: {
           title: '排课ID',
           type: 'text',
           column: {
@@ -49,7 +69,7 @@ function curd({ context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
           type: 'easDateTime',
           sortable: true,
           column: {
-            width: 180
+            show: false
           }
         },
         morning: {
@@ -66,8 +86,7 @@ function curd({ context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
             ]
           }),
           column: {
-            resizable: true,
-            width: 180
+            resizable: true
           }
         },
         afternoon: {
@@ -84,15 +103,21 @@ function curd({ context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
             ]
           }),
           column: {
-            resizable: true,
-            width: 180
+            resizable: true
           }
         },
         studentName: {
           title: '学生姓名',
           type: 'text',
+          sortable: true
+        },
+        type: {
+          title: '类别',
+          type: 'text',
           sortable: true,
-          width: 100
+          form: {
+            show: false
+          }
         },
         studentNumber: {
           title: '学生学号',
@@ -102,32 +127,42 @@ function curd({ context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
             width: 280
           }
         },
-        createUid: {
-          title: '录入用户',
+        teacherName: {
+          title: '授课老师',
           type: 'text',
           sortable: true,
           width: 60,
+          search: {
+            show: false
+          },
           form: {
             show: false
           }
         },
-        createTime: {
-          title: '创建时间',
-          type: 'easDateTime',
+        categoryName: {
+          title: '类别',
+          type: 'text',
           sortable: true,
           width: 100,
           form: {
             show: false
           }
         },
-        modifyTime: {
-          title: '修改时间',
-          type: 'easDateTime',
+        subjectsName: {
+          title: '系列',
+          type: 'text',
           sortable: true,
           width: 100,
           form: {
             show: false
           }
+        },
+        roomName: {
+          title: '教室',
+          type: 'text',
+          form: {
+            show: false
+          }
         }
       }
     }

+ 84 - 0
src/views/management/attendance/api.ts

@@ -0,0 +1,84 @@
+import { request } from '@/service/request';
+
+// 参数接口
+export interface GetAttendanceListParams {
+  id?: number;
+  studentId?: number;
+  month?: number;
+  startTime?: string;
+  endTime?: string;
+  teacherId?: number;
+  classId?: number;
+}
+
+// 响应接口
+export interface GetStudentListRes {
+  status: boolean;
+  msg: string;
+  data: Record<string, unknown>;
+  total: number;
+}
+
+/**
+ * 综合查询签到打卡信息
+ * @param {string} pageNum
+ * @param {string} pageSize
+ * @param {object} params AttendanceDto
+ * @param {number} params.id
+ * @param {number} params.studentId
+ * @param {number} params.month
+ * @param {object} params.startTime
+ * @param {object} params.endTime
+ * @param {number} params.teacherId
+ * @param {number} params.classId
+ * @returns
+ */
+export function queryAttendance(
+  pageNum: number,
+  pageSize: number,
+  params: GetAttendanceListParams
+): Promise<Service.RequestResult<GetStudentListRes[]>> {
+  return request.post(`/attendance/queryAttendance?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`);
+}
+
+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);
+}

+ 255 - 0
src/views/management/attendance/crud.ts

@@ -0,0 +1,255 @@
+import type { CreateCrudOptionsRet } from '@fast-crud/fast-crud';
+import { dict } from '@fast-crud/fast-crud';
+import { queryAttendance, queryClassAll, queryClassRoomList } from './api';
+function curd(): CreateCrudOptionsRet {
+  return {
+    crudOptions: {
+      request: {
+        pageRequest: async ({ page, query }) => {
+          const { total, data } = await queryAttendance(page.offset + 1, page.limit, query);
+          return { records: data, total, currentPage: page.offset, pageSize: page.limit };
+        }
+      },
+      toolbar: {
+        show: true
+      },
+      actionbar: {
+        show: false
+      },
+      rowHandle: {
+        show: false,
+        buttons: {
+          remove: {
+            show: false
+          },
+          add: {
+            show: false
+          },
+          edit: {
+            show: false
+          },
+          view: {
+            show: false
+          }
+        }
+      },
+      columns: {
+        id: {
+          title: '排课ID',
+          type: 'text',
+          search: {
+            show: true
+          },
+          column: {
+            show: true
+          }
+        },
+        checkinDate: {
+          title: '签到日期',
+          type: 'text',
+          search: {
+            show: false
+          },
+          column: {
+            show: false
+          }
+        },
+        morning: {
+          title: '上午',
+          type: 'dict-select',
+          dict: dict({
+            data: [
+              // a  表示正常出勤,   b  表示迟到、早退, c  表示旷课, d  表示请假, e表示无效
+              { value: 'a', label: '正常' },
+              { value: 'b', label: '迟到/早退' },
+              { value: 'c', label: '旷课' },
+              { value: 'd', label: '请假' },
+              { value: 'e', label: '无效' }
+            ]
+          }),
+          search: {
+            show: false
+          },
+          column: {
+            resizable: true,
+            align: 'center',
+            fixed: 'left'
+          }
+        },
+        afternoon: {
+          title: '下午',
+          type: 'dict-select',
+          dict: dict({
+            data: [
+              // a  表示正常出勤,   b  表示迟到、早退, c  表示旷课, d  表示请假, e表示无效
+              { value: 'a', label: '正常' },
+              { value: 'b', label: '迟到/早退' },
+              { value: 'c', label: '旷课' },
+              { value: 'd', label: '请假' },
+              { value: 'e', label: '无效' }
+            ]
+          }),
+          search: {
+            show: false
+          },
+          column: {
+            resizable: true,
+            align: 'center',
+            fixed: 'left'
+          }
+        },
+        month: {
+          title: '月份',
+          type: 'text',
+          search: {
+            show: true
+          },
+          column: {
+            resizable: true,
+            width: 20,
+            align: 'center',
+            fixed: 'left'
+          }
+        },
+        studentId: {
+          title: '学生ID',
+          type: 'text',
+          search: {
+            show: true
+          },
+          column: {
+            resizable: true,
+            align: 'center',
+            fixed: 'left'
+          }
+        },
+        type: {
+          title: '类型',
+          type: 'text',
+          search: {
+            show: false
+          },
+          column: {
+            resizable: true,
+            align: 'center',
+            fixed: 'left'
+          }
+        },
+        className: {
+          title: '班级',
+          search: {
+            show: true
+          },
+          column: {
+            resizable: true,
+            align: 'center',
+            fixed: 'left'
+          },
+          type: 'dict-select',
+          dict: dict({
+            async getData() {
+              const result = await queryClassAll();
+              return result.data?.map(r => {
+                return {
+                  label: r.name,
+                  value: r.id
+                };
+              }) as any[];
+            }
+          })
+        },
+        startTime: {
+          title: '开始时间',
+          type: 'easDateTime',
+          search: {
+            show: true
+          },
+          column: {
+            resizable: true,
+            align: 'center',
+            fixed: 'left'
+          }
+        },
+        endTime: {
+          title: '结束时间',
+          type: 'easDateTime',
+          search: {
+            show: true
+          },
+          column: {
+            resizable: true,
+            align: 'center',
+            fixed: 'left'
+          }
+        },
+        categoryName: {
+          title: '类别名称',
+          type: 'text',
+          search: {
+            show: false
+          },
+          column: {
+            resizable: true,
+            align: 'center',
+            fixed: 'left'
+          }
+        },
+        subjectsName: {
+          title: '科目名称',
+          type: 'text',
+          search: {
+            show: false
+          },
+          column: {
+            resizable: true,
+            align: 'center',
+            fixed: 'left'
+          }
+        },
+        studentName: {
+          title: '姓名',
+          type: 'text',
+          search: {
+            show: true
+          },
+          column: {
+            resizable: true,
+            align: 'center',
+            fixed: 'left'
+          }
+        },
+        teacherName: {
+          title: '教师姓名',
+          type: 'text',
+          search: {
+            show: false
+          },
+          column: {
+            resizable: true,
+            align: 'center',
+            fixed: 'left'
+          }
+        },
+        roomName: {
+          search: {
+            show: true
+          },
+          title: '教室',
+          type: 'dict-select',
+          dict: dict({
+            async getData() {
+              const result = await queryClassRoomList(1, 100, {});
+              return result.data?.map(r => {
+                return {
+                  label: r.name,
+                  value: r.id
+                };
+              }) as any[];
+            }
+          })
+        }
+      }
+    }
+  };
+}
+export default curd;

+ 17 - 0
src/views/management/attendance/index.vue

@@ -0,0 +1,17 @@
+<template>
+  <div class="h-full bg-white">
+    <fs-crud ref="crudRef" v-bind="crudBinding" />
+  </div>
+</template>
+<script setup lang="ts">
+import { onMounted } from 'vue';
+import { useFs } from '@fast-crud/fast-crud';
+import createCrudOptions from './crud';
+
+const { crudRef, crudBinding, crudExpose } = useFs({ createCrudOptions });
+
+onMounted(() => {
+  crudExpose.doRefresh();
+});
+</script>
+<style scoped></style>