教材管理系统
文章目录
- 教材管理系统
- 一、系统演示
- 二、项目介绍
- 三、系统部分功能截图
- 四、部分代码展示
- 五、底部获取项目源码(9.9¥带走)
教材管理系统
一、系统演示
教材管理系统
二、项目介绍
语言:nodejs
框架:egg.js、Vue
数据库:MySQL
三个角色:管理员、教师、学生
用户管理、角色管理、菜单管理、教材数据、教材征订、出入库记录、领书操作、领书分析、班级管理、课程信息、教师信息
三、系统部分功能截图








四、部分代码展示
import { createRouter, createWebHashHistory } from 'vue-router'
import { getToken } from '../utils/cookie'
import { roleMenu } from '@/api/login'
import store from '@/store'export const constantRoutes = [{path: '/login',name: 'Login',hidden: '1',component: () => import(/* webpackChunkName: "login" */ '../views/login/Login.vue')},{path: '/change/psw',component: () => import('../views/index/Home.vue'),redirect: '/change/psw',hidden: '1',children: [{path: '',component: () => import('@/views/index/ChangePsw'),name: 'ChangePsw',hidden: '0',meta: { title: '修改密码', icon: '' }}]},{path: '/:w+',component: () => import('@/views/index/404.vue'),hidden: '1'}
]const router = createRouter({history: createWebHashHistory(),routes: constantRoutes
})const whiteList = ['/login']
router.beforeEach((to, from, next) => {document.title = to.meta.title || '系统'const token = getToken()if (token) {if (to.path === '/login') {next('/')} else {if (store.getters.addRouters.length === 0) {roleMenu().then(res => {store.dispatch('generateRoutes', res.data).then(() => {store.getters.addRouters.forEach(item => {router.addRoute(item)})next({ ...to, replace: true })})})store.dispatch('getCurUserInfo')} else {next()}}} else {if (whiteList.indexOf(to.path) !== -1) {next()} else {next('/login')}}
})router.afterEach((to, from) => {setKeepAlive(to)
})function setKeepAlive(to) {if(to.meta.keep_alive === '1') {store.commit("setKeepAlive", to.name);}
}export default router
<template><div style="padding:20px;margin:20px;"><el-form :inline="true" :model="seacheForm" size="small"><el-form-item label="教材"><el-input v-model="seacheForm.book" clearable placeholder="请输入教材名称" size="small" /></el-form-item><el-form-item label="书号"><el-input v-model="seacheForm.ISBN" clearable placeholder="请输入教材书号" size="small" /></el-form-item><el-form-item><el-button type="primary" size="small" @click="refresh">搜索</el-button></el-form-item></el-form><el-table :data="bookTable" v-loading="tableLoading" size="small" style="width: 100%"><el-table-column type="index" label="序号" align="center" fixed="left" width="55" /><el-table-column prop="book" align="center" label="教材名称" fixed="left" width="200" show-overflow-tooltip /><el-table-column prop="editor" align="center" label="主编" show-overflow-tooltip /><el-table-column prop="pubDate" align="center" label="出版时间" show-overflow-tooltip /><el-table-column prop="ISBN" align="center" label="书号" show-overflow-tooltip /><el-table-column prop="publisher" align="center" label="出版社" show-overflow-tooltip /><el-table-column prop="book_type" align="center" label="教材类型" show-overflow-tooltip /><el-table-column prop="book_usage" align="center" label="使用情况" show-overflow-tooltip /><el-table-column prop="price" align="center" label="单价" show-overflow-tooltip /><el-table-column prop="book_total" align="center" label="教材库存" fixed="right" show-overflow-tooltip /><el-table-column fixed="right" label="操作" align="center" width="120"><template #default="{row}"><el-button type="primary" size="small" @click="handleAddBook(row)">增订</el-button></template></el-table-column></el-table><div class="demo-pagination-block"><el-paginationv-model:currentPage="currentPage"v-model:page-size="pageSize":page-sizes="[8, 20, 30, 50]":background="false"layout="total, sizes, prev, pager, next, jumper":total="total"@size-change="handleSizeChange"@current-change="handleCurrentChange"/></div> <el-dialog v-model="addDialog" title="续订教材" width="55%"><el-form :model="form" :inline="true" :rules="rules" ref="ruleFormRef" label-width="120px"><el-form-item label="教材名称" prop="book"><el-input v-model="form.book" disabled placeholder="请输入教材名称" /> </el-form-item><el-form-item label="学生用书" prop="sdt_book_nums"><el-input v-model.number="form.sdt_book_nums" placeholder="请输入学生用书数量" /> </el-form-item><el-form-item label="学生备用" prop="standby_nums"><el-input v-model.number="form.standby_nums" placeholder="请输入学生备用书数量" /> </el-form-item><el-form-item label="教师用书" prop="tch_book_nums"><el-input v-model.number="form.tch_book_nums" placeholder="请输入教师用书数量" /> </el-form-item><el-form-item label="教材单价" prop="price"><el-input v-model.number="form.price" disabled placeholder="请输入教材单价(单位:元)" /> </el-form-item><el-form-item label="教材总数"><el-input v-model.number="bookTotal" disabled placeholder="教材总价" /> </el-form-item><el-form-item label="教材总价"><el-input v-model.number="bookPriceTotal" disabled placeholder="教材总价" /> </el-form-item><el-form-item label="教材使用情况" prop="book_usage"><el-select v-model="form.book_usage" placeholder="请选择教材使用情况"><el-option label="选用" value="选用" /><el-option label="不选用" value="不选用" /></el-select></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="addDialog=false">取消</el-button><el-button type="primary" @click="onSubmit">确定</el-button></span></template></el-dialog></div>
</template>
<script setup>
import { ElMessage,ElMessageBox } from 'element-plus';
import { computed, onMounted, reactive, ref} from 'vue';
import { operateRecord, operateStore } from '@/api/book/operate';
import { getRecordDetail } from '@/api/education/operate';
import dayjs from 'dayjs';
onMounted(()=>{refresh();
})
const tableLoading = ref(false);
const refresh = () =>{tableLoading.value = true;operateStore({limit:pageSize.value,page:currentPage.value,book:seacheForm.book,ISBN:seacheForm.ISBN,}).then(res=>{bookTable.value = res.data.rows;total.value = res.data.count;bookTable.value.forEach((item)=>{item.pubDate ? item.pubDate = dayjs(item.birth).format('YYYY-MM') : ''})tableLoading.value = false;})
}// 搜索表单
const seacheForm = reactive({});// 表格
const bookTable = ref([]);
const total = ref(0);
const bookTotal = computed(()=>{let total = form.value.sdt_book_nums + form.value.standby_nums + form.value.tch_book_nums;return total;
})
const bookPriceTotal = computed(()=>{let total = (form.value.sdt_book_nums + form.value.standby_nums + form.value.tch_book_nums) * Number(form.value.price);return total;
})
const addDialog = ref(false);
const form = ref({});
const handleAddBook = (row) =>{getRecordDetail({record_id:row.record_id}).then(res=>{form.value = res.data[0];form.value.sdt_book_nums=0form.value.standby_nums=0form.value.tch_book_nums=0addDialog.value = true;})
}const onSubmit = () =>{if(bookTotal.value==0){ElMessage({type:'warning',message:'未填写征订数量!'});return;}delete form.value.id;form.value.total = bookPriceTotal.value;form.value.book_total = bookTotal.value;form.value.apply = 1;operateRecord({data:form.value,flag:1}).then(res=>{if(res.success){ElMessage({type:'success',message:'申请成功!'});addDialog.value = false;}else{ElMessage({type:'danger',message:'申请失败!'});}})
}// 分页
const currentPage = ref(1);
const pageSize = ref(8);
const handleSizeChange = (val) => {pageSize.value = val;refresh();
}
const handleCurrentChange = (val) => {currentPage.value = val;refresh();
}</script><style>
</style>
import { createRouter, createWebHashHistory } from 'vue-router'
import { getToken } from '../utils/cookie'
import { roleMenu } from '@/api/login'
import store from '@/store'export const constantRoutes = [{path: '/login',name: 'Login',hidden: '1',component: () => import(/* webpackChunkName: "login" */ '../views/login/Login.vue')},{path: '/change/psw',component: () => import('../views/index/Home.vue'),redirect: '/change/psw',hidden: '1',children: [{path: '',component: () => import('@/views/index/ChangePsw'),name: 'ChangePsw',hidden: '0',meta: { title: '修改密码', icon: '' }}]},{path: '/:w+',component: () => import('@/views/index/404.vue'),hidden: '1'}
]const router = createRouter({history: createWebHashHistory(),routes: constantRoutes
})const whiteList = ['/login']
router.beforeEach((to, from, next) => {document.title = to.meta.title || '系统'const token = getToken()if (token) {if (to.path === '/login') {next('/')} else {if (store.getters.addRouters.length === 0) {roleMenu().then(res => {store.dispatch('generateRoutes', res.data).then(() => {store.getters.addRouters.forEach(item => {router.addRoute(item)})next({ ...to, replace: true })})})store.dispatch('getCurUserInfo')} else {next()}}} else {if (whiteList.indexOf(to.path) !== -1) {next()} else {next('/login')}}
})router.afterEach((to, from) => {setKeepAlive(to)
})function setKeepAlive(to) {if(to.meta.keep_alive === '1') {store.commit("setKeepAlive", to.name);}
}export default router
五、底部获取项目源码(9.9¥带走)
有问题,或者需要协助调试运行项目的也可以
相关文章:
教材管理系统
文章目录 教材管理系统一、系统演示二、项目介绍三、系统部分功能截图四、部分代码展示五、底部获取项目源码(9.9¥带走) 教材管理系统 一、系统演示 教材管理系统 二、项目介绍 语言:nodejs 框架:egg.js、Vue 数据库…...
PV、UV、IP
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言1. PV1.1 PV 计算1.2 PV 的影响因素 2. UV2.1 UV 计算2.2UV 的影响因素 3. IP3.1 IP和UV①UV大于IP②UV小于IP 三者的关系PV 和 UV 前言 PV、UV、IP是我们在运…...
ZigBee学习——在官方例程上实现串口通信
Z-Stack版本为3.0.2 IAR版本为10.10.1 文章目录 一、添加头文件二、定义接收缓冲区三、编写Uart初始化函数四、编写串口回调函数五、函数声明六、函数调用七、可能遇到的问题(function “halUartInit“ has no prototype) 以下所有操作都是在APP层进行,也就是这个文…...
nginx添加lua模块
目录 已安装了nginx,后追加lua模块nginx 重新编译知识参考: 从零安装一、首先需要安装必要的库(pcre、zlib、openssl)二、安装LUA环境及相关库 (LuaJIT、ngx_devel_kit、lua-nginx-module)注意:…...
Csapp-chapter3-压栈和弹栈
bp与sp(压栈和弹栈) 在计算机内部的寄存器组中,有一对寄存器非常有意思:%ebp,%esp 文章目录 bp与sp(压栈和弹栈)寄存器组示例图%ebp与%esp总结 寄存器组示例图 首先我们应该对于计算机中的寄存…...
Rust入门1——HelloWorld
文章目录 一、HelloWorld二、控制台输入 以最简单的两个Rust程序例子入门Rust。首先需要下载安装Rust,之后在VSCode或Clion中运行Rust需要下载Rust插件 一、HelloWorld fn main(){println!("Hello World!"); }二、控制台输入 use std::io::stdin; fn …...
android中使用Bitmp对象绘制图形
1、引言 你是否还在因为不懂UI设计而不得不去借用别人的图片,甚至使用各种网图作为界面布局的一部分,那么今天就教你使用Bitmap对象去绘制自定义图形,并保存为png格式的图片,须知图片编辑软件本就是程序员开发出来的,我…...
Linux操作系统基础(八):Linux的vi/vim编辑器
文章目录 Linux的vi/vim编辑器 一、vi/vim编辑器介绍 二、打开文件 三、VIM编辑器的三种模式(重点) 四、命令模式相关命令 五、底行模式相关命令 Linux的vi/vim编辑器 一、vi/vim编辑器介绍 vi是visual interface的简称, 是Linux中最经典的文本编辑器 vi的核心设计思想…...
nginx限制网段访问
文章目录 nginx限制网段访问介绍:使用:示例:介绍网段:nginx限制网段访问 介绍: Nginx的deny和allow指令是由ngx_http_access_module模块提供, Nginx安装默认内置了该模块 使用: nginx访问控制模块: 想禁止哪个ip访问就加上deny IP, 想允许哪个ip访问就加上allow…...
Linux开机自动执行自定义脚本或命令
尝试了多种方法,现总结如下: 在用户登录之前自动执行 1. /etc/init.d/rcS 2. /etc/inittab 在用户登录之后自动执行:下述方法,实际尝试发现,之后再输入用户名和密码后才会自动执行。当如果不需要输入用户名或密码时…...
【Linux】 网络编程套接字
目录 预备知识 网络字节序 网络字节序和主机字节序转换的库函数 socket编程接口 socket常见API sockaddr结构 套接字的种类 预备知识 1.在IP数据包头部中,有两个IP地址,分别叫做源IP地址和目的IP地址。 2.端口号:是传输层协议的内容…...
MATLAB矩阵的操作(第二部分)
师从清风 矩阵的创建方法 在MATLAB中,矩阵的创建方法主要有三种,分别是:直接输入法、函数创建法和导入本地文件中的数据。 直接输入法 输入矩阵时要以中括号“[ ]”作为标识符号,矩阵的所有元素必须都在中括号内。 矩阵的同行元…...
基础面试题整理6之Redis
1.Redis的应用场景 Redis支持类型:String、hash、set、zset、list String类型 hash类型 set类型 zset类型 list类型 一般用作缓存,例如 如何同时操作同一功能 2.redis是单线程 Redis服务端(数据操作)是单线程,所以Redis是并发安全的,因…...
MySQL基础查询篇(7)-常用的字符串函数
MySQL数据库是目前广泛应用于各种系统中的一种关系型数据库管理系统。在MySQL中,有许多常见的字符串函数,可以对字符串进行各种处理和操作。本文将介绍MySQL数据库中常用的一些字符串函数,并提供详细示例。 CONCAT函数:用于将两个…...
如何实现视线(目光)的检测与实时跟踪
如何实现视线(目光)的检测与实时跟踪 核心步骤展示说明 找到人脸 检测人脸特征点 根据特征点找到人眼区域 高精度梯度算法检测瞳孔中心 根据眼睛周边特征点计算眼睛中心 瞳孔中心和眼睛中心基于视线模型计算视线方向 视线方向可视化 详细实现与说明: https://stud…...
STM32 FSMC (Flexible static memory controller) 灵活静态内存控制器介绍
文章目录 1. 介绍FSMC2. FSMC特点3. Block示意图4. AHB接口4.1 Supported memories and transactionsGeneral transaction rulesConfiguration registers 5. 外部设备地址映射5.1 NOR/PSRAM地址映射将NOR Flash/PSRAM的支持进行封装 5.2 NAND/PC Card地址映射 1. 介绍FSMC 说到…...
手把手教你开发Python桌面应用-PyQt6图书管理系统-图书信息维护模块UI设计实现
锋哥原创的PyQt6图书管理系统视频教程: PyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~_哔哩哔哩_bilibiliPyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~共计24条视频&…...
SpringBoot源码解读与原理分析(六)WebMvc场景的自动装配
文章目录 2.6 WebMvc场景下的自动装配原理2.6.1 WebMvcAutoConfiguration2.6.2 Servlet容器的装配2.6.2.1 EmbeddedTomcat、EmbeddedJetty、EmbeddedUndertow2.6.2.2 BeanPostProcessorsRegistrar(后置处理器的注册器)2.6.2.3 两个定制器的注册 2.6.3 DispatcherServlet的装配2…...
git恢复rebase过程中遇到权限问题和丢失的提交
文章目录 一、检查丢失的提交是否还在 reflog 中二、创建一个新分支来恢复丢失的提交三、处理权限问题四. 使用 git fsck 查找丢失对象1、创建一个新分支来恢复该提交2、检查和合并提交 五. 介绍git中命令reflog 与 fsck1、git reflog2、git fsck使用场景 一、检查丢失的提交是…...
Spring boot 集成redis
一、使用spring bootspring-boot-starter-data-redis 导入maven包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> spring boot配置文件 spring.re…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...
