# Vue-实验室预约系统 **Repository Path**: cricosly/vue-laboratory-reservation-system ## Basic Information - **Project Name**: Vue-实验室预约系统 - **Description**: 一个允许教师灵活预约课程实验时间的实验室预约系统 - **Primary Language**: Unknown - **License**: AGPL-3.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 1 - **Created**: 2024-05-21 - **Last Updated**: 2025-07-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: Vue, Ant-Design, Element-UI, TypeScript ## README

Logo

" Vue-Laboratory "

基于 Vue3 + TypeScript 的实验室预约系统【纯Vue前端版】

![star](https://gitee.com/cricosly/vue-laboratory-reservation-system/badge/star.svg?theme=dark) ![fork](https://gitee.com/cricosly/vue-laboratory-reservation-system/badge/fork.svg?theme=dark)

## 快速开始 1. 克隆本仓库到本地 2. 安装Node.js 20 3. 安装依赖 ``` npm install ``` 4. 本地启动 ``` npm run dev ``` 5. 打包生产环境 ``` npm run build ``` 6. 体验用户 ``` 账号: admin 密码: admin ``` ## 技术框架 **开发环境** >Visual Studio Code ^1.89.1 Node.js ^20.11.1 ...... **Vite/Vue3前端框架** >Vite ^5.1.5 Vue ^3.4.21 Vue-router ^4.3.0 VueUse ^10.9.0 (替代Pinia/Axios) ...... **Ant-Design-Vue: ^4.2.1 UI框架** >layout 布局,协助进行页面级整体布局。 ant-design/icons-vue 图标 Notification 通知提醒框 ...... **Element-Plus: ^2.7.3 UI框架** >Icon 图标 Form 表单 Slider 滑动输入条 Message 全局提示 Popconfirm 气泡确认框 Tabs 卡片风格标签页 Input Number 数字输入框 ...... ## 约定 **课程** 课程有课时规定,`1节课=1课时` **实验室** 系统默认包含4个实验室可以预约 包括`905实验室、906实验室、907实验室、908实验室` **预约** 共`18`周课程,每周`7`天皆可预约 每天的节次规定`按段预约`,即`1~2`节、`3~4`节、`5~6`节、`7~8`节为一段 **登录** 系统需`登录使用`,并根据登录信息验证教师身份 预约基于登录的身份进行,系统有6位老师,用户名密码一致 > admin 1001 1002 1003 1004 1005 ## 需求与设计 **课程管理** 1、教师可以查看自己的课程 2、教师可以创建包含课程名称,学时的实验课若干 3、后续基于录入的课程进行预约 3、教师可以修改已有课程,修改后同步修改预约情况信息里的课程名字 ```js // 更新ytimes预约表中对应课程的名字 if (editingCourse && editingCourse.name !== editForm.value.name) { ytimesR.value = ytimesR.value.map((ytime) => { if (ytime.cid === editingCourse?.cid) { return { ...ytime, cname: editForm.value.name } } return ytime }) } ``` 4、教师可以删除已有课程,已有预约信息的课程无法删除 ```js // 删除课程 const deleteCourse = (course: Course) => { // 在预约表中检查课程是否存在 const isInYtimes = ytimesR.value.some((ytime) => ytime.cid === course.cid) if (isInYtimes) { // 如果在预约表中存在,则拒绝删除并给出提示 error('错误! 该课程存在预约信息,不能删除') return // 直接返回,不执行后续删除操作 } const index = tableData.value.findIndex((c) => c.cid === course.cid) if (index !== -1) { tableData.value.splice(index, 1) } } ``` **课表信息** 1、可以查看所有的周次每天的所有课程安排情况 2、课程信息表示为: > 课程名称 > 老师名称 > 实验室 / 周次 3、通过颜色区分实验室 ```js // 实验室颜色映射 const roomColorMap: { [key: string]: string } = { '905': '#eea6b7', // 实验室905对应红色 '906': 'rgb(137, 222, 255)', // 实验室906对应蓝色 '907': '#5dbe8a', // 实验室907对应绿色 '908': '#f6ad8f' // 实验室908对应橙色 // 其他实验室... } ``` 4、突出显示当前登录老师自己的课程,红色虚线框为当前登录老师的课程 ```js const borderColor = (name: string) => { return userS.value.name === name ? '2px dashed #ee2746' : '' } ``` **实验室预约** 1、分每个实验室以大表格形式渲染显示18周内每天每段的占用情况 2、红色为当前登录老师的课程占用情况,蓝色为其他老师的课程占用情况 3、实验时间固定,预约需要选择课程、实验室、周次、星期、节次 4、预约学时不能大于剩余学时,预约成功后更新剩余学时 ```js // 学时冲突检查 if (appointmentHours > remainHours!) { error('错误! 预约学时不可超过剩余学时') return // 退出函数,不保存更改 } // 更新课程剩余学时 const index = coursesR.value.findIndex((c) => c.cid === newCourse!.cid) // 如果找到了索引,更新课程的剩余学时 if (index !== -1) { const updatedCourse = { ...newCourse, remainhours: newRemainHours } coursesR.value.splice(index, 1, updatedCourse) } ``` 5、预约实验室时间冲突:同一个实验室,同一时间不能有多门课程 6、预约个人时间冲突:同一个老师,同一时间不能在不同的实验室上课 ```js // 时间冲突检查 function checkConflict(addForm: Ytime, ytimes: Ytime[]): string { for (const ytime of ytimes) { // 实验室时间冲突 if (addForm.room === ytime.room) { if ( // 星期相同 addForm.day === ytime.day && // 节次相同 addForm.time![0] === ytime.time![0] && addForm.time![1] === ytime.time![1] ) { // 周次有交集 if (!(addForm.end! < ytime.start! || addForm.start! > ytime.end!)) { // 存在冲突 return '实验室时间冲突' } } } // 个人时间冲突 if (addForm.uid === ytime.uid) { if ( // 星期相同 addForm.day === ytime.day && // 节次相同 addForm.time![0] === ytime.time![0] && addForm.time![1] === ytime.time![1] ) { // 周次有交集 if (!(addForm.end! < ytime.start! || addForm.start! > ytime.end!)) { // 存在冲突 return '个人时间冲突' } } } } // 无冲突 return '可预约' } ``` ## 打包部署 所有文件的引用必修使用相对路径 `vite.config.ts`添加配置,按相对路径编译。 ```js export default defineConfig({ plugins: [vue()], base: './', // 相对路径打包 // ... }) ``` 运行`npm run build`命令,在项目下生成编译结果`dist`目录。 ```shell npm run build ``` 打包报错,大小超限制 `vite.config.ts`添加配置 加大限制的大小将500kb改成2500kb或者更大 分解块,将大块分解成更小的块 ```ts build: { chunkSizeWarningLimit: 2500, rollupOptions: { output: { manualChunks(id) { if (id.includes('node_modules')) { return id.toString().split('node_modules/')[1].split('/')[0].toString() } } } } }, ``` 资源管理器进入`dist`目录,将目录下全部文件(`index.html`+`assets`)压缩为`zip`文件。 将`zip`文件扩展名修改为`war`,即`dist.war`。`zip/war`使用相同的压缩算法。 注意:压缩包内`不要嵌套文件夹`,内部直接就是`dist`目录中的文件 登录平台,上传war包自动部署。 基于腾讯云轻量级应用服务器进行部署 使用Xftp、Xshell进行部署管理 Nginx配置文件 nginx.conf ```config server { location / { root /var/Vue-Laboratory; index index.html index.htm; try_files $uri $uri/ /index.html; # 解决404 } ```