圖書管理系統練習項目源碼-前后端分離-使用node.js來做后端開發

前端學習了這么久了,node.js 也有了一定的了解,知道使用node也可以來開發后端,今天給大家分享 使用node 來做后端,vue來寫前端,做一個簡單的圖書管理系統。我們在剛開始學習編程的時候,需要自己寫大量的項目來練習自己的編程技能,在開發中你會遇到各種各樣的編程問題,這個時候 就可以根據自己學習到的編程知識來解決開發中遇到的問題,這樣我們就會慢慢的掌握一門編程語言。
今天分享的就是我最近寫的一個圖書管理系統。
使用技術:
Node.js:后端使用Node.js平臺,版本要求16.20以上,基于其高性能和跨平臺特性,能夠輕松支持大規模的API請求。

Express框架:簡潔高效的后端框架,幫助快速搭建API服務。

MySQL 5.7:作為關系型數據庫管理系統,MySQL用于存儲用戶和圖書信息,并支持CRUD操作。

Vue2:前端使用Vue2框架,配合Element UI組件庫,提供響應式頁面和現代化用戶界面。

Element UI:幫助實現簡潔且功能豐富的UI設計,極大提高了前端開發效率。

系統功能
用戶管理:可以新增、編輯、刪除用戶信息。

圖書管理:添加、修改、刪除圖書,并能夠查看圖書列表。

借閱管理:記錄圖書借閱、歸還情況。

數據展示:通過前端頁面展示系統中的圖書、用戶信息,提供了簡潔、易用的界面。
部分頁面效果展示:
在這里插入圖片描述
在這里插入圖片描述
目錄結構:
在這里插入圖片描述
部分前端代碼:

<template><div class="app-container"><!-- 搜索和操作欄 --><div class="filter-container"><el-inputv-model="listQuery.name"placeholder="請輸入圖書名稱"style="width: 200px; margin-right: 10px"class="filter-item"@keyup.enter.native="handleFilter"/><el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">搜索</el-button><el-button type="primary" @click="handleCreate" style="margin-left: 10px">新增圖書</el-button></div><!-- 數據表格 --><el-tablev-loading="listLoading":data="list"element-loading-text="加載中..."borderfithighlight-current-rowstyle="margin-top: 20px;"><el-table-column label="圖書編號" prop="book_no" align="center" /><el-table-column label="圖書名稱" prop="name" align="center" /><el-table-column label="分類" prop="category_name" align="center" /><el-table-column label="作者" prop="author" align="center" /><el-table-column label="使用狀態" align="center"><template slot-scope="{row}"><el-tag :type="row.use_status === 0 ? 'info' : row.use_status === 1 ? 'success' : 'warning'">{{ row.use_status === 0 ? '在書架' : row.use_status === 1 ? '已買' : '已借出' }}</el-tag></template></el-table-column><el-table-column label="是否二手" align="center"><template slot-scope="{row}"><el-tag :type="row.is_second_hand === 1 ? 'warning' : 'info'">{{ row.is_second_hand === 1 ? '是' : '否' }}</el-tag></template></el-table-column><el-table-column label="狀態" align="center"><template slot-scope="{row}"><el-tag :type="row.status === 1 ? 'success' : 'danger'"  style="cursor: pointer">{{ row.status === 1 ? '正常' : '維護' }}</el-tag></template></el-table-column><el-table-column label="備注" prop="remark" align="center" show-overflow-tooltip /><el-table-column label="創建時間" prop="created_at" align="center" /><el-table-column label="操作" align="center" width="160" fixed="right"><template slot-scope="{row}"><el-button type="primary" size="mini" @click="handleUpdate(row)">編輯</el-button><el-button type="danger" size="mini" @click="handleDelete(row)">刪除</el-button></template></el-table-column></el-table><!-- 新增/編輯對話框 --><el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="600px"><el-formref="dataForm":model="temp":rules="rules"label-position="left"label-width="100px"style="margin-left: 50px; margin-right: 50px"><el-form-item label="圖書編號" prop="book_no"><el-input v-model="temp.book_no" placeholder="請輸入圖書編號" /></el-form-item><el-form-item label="圖書名稱" prop="name"><el-input v-model="temp.name" placeholder="請輸入圖書名稱" /></el-form-item><el-form-item label="圖書分類" prop="category_id"><el-select v-model="temp.category_id" placeholder="請選擇圖書分類" style="width: 100%"><el-optionv-for="item in categories":key="item.id":label="item.name":value="item.id"/></el-select></el-form-item><el-form-item label="作者" prop="author"><el-input v-model="temp.author" placeholder="請輸入作者" /></el-form-item><el-form-item label="出版日期" prop="publish_date"><el-date-pickerv-model="temp.publish_date"type="datetime"placeholder="請選擇出版日期"style="width: 100%"/></el-form-item><el-form-item label="定價" prop="price"><el-input-numberv-model="temp.price":precision="2":step="0.1":min="0"style="width: 100%"/></el-form-item><el-form-item label="狀態" prop="status"><el-select v-model="temp.status" placeholder="請選擇狀態" style="width: 100%"><el-option label="正常" :value="1" /><el-option label="維護" :value="0" /></el-select></el-form-item><el-form-item label="使用狀態" prop="use_status"><el-select v-model="temp.use_status" placeholder="請選擇使用狀態" style="width: 100%"><el-option label="在書架" :value="0" /><el-option label="已買" :value="1" /><el-option label="已借出" :value="2" /></el-select></el-form-item><el-form-item label="是否二手" prop="is_second_hand"><el-select v-model="temp.is_second_hand" placeholder="請選擇是否二手" style="width: 100%"><el-option label="否" :value="0" /><el-option label="是" :value="1" /></el-select></el-form-item><el-form-item label="備注" prop="remark"><el-inputv-model="temp.remark"type="textarea"placeholder="請輸入備注信息":rows="3"/></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false">取消</el-button><el-button type="primary" @click="submitForm">確定</el-button></div></el-dialog></div>
</template><script>
import {getBookList,createBook,updateBook,deleteBook,updateBookStatus
} from '@/api/book'
import { getCategoryList } from '@/api/category'export default {name: 'BookList',data() {return {list: [], // 圖書列表數據categories: [], // 分類列表數據listLoading: false, // 列表加載狀態listQuery: { // 查詢參數name: '' // 圖書名稱搜索關鍵詞},dialogVisible: false, // 對話框顯示狀態dialogTitle: '', // 對話框標題temp: { // 臨時數據對象id: undefined,book_no: '',name: '',category_id: undefined,author: '',publish_date: undefined,price: 0,status: 1,remark: '',use_status: 0,is_second_hand: 0},rules: { // 表單驗證規則book_no: [{ required: true, message: '請輸入圖書編號', trigger: 'blur' }],name: [{ required: true, message: '請輸入圖書名稱', trigger: 'blur' }],category_id: [{ required: true, message: '請選擇圖書分類', trigger: 'change' }],author: [{ required: true, message: '請輸入作者', trigger: 'blur' }],publish_date: [{ required: true, message: '請選擇出版日期', trigger: 'change' }],price: [{ required: true, message: '請輸入定價', trigger: 'blur' }]}}},created() {this.getList()this.getCategories()},methods: {// 獲取圖書列表async getList() {try {this.listLoading = trueconst { data } = await getBookList(this.listQuery)this.list = data} catch (error) {console.error('獲取圖書列表失敗:', error)} finally {this.listLoading = false}},// 處理搜索handleFilter() {this.getList()},// 獲取分類列表async getCategories() {try {const { data } = await getCategoryList()this.categories = data} catch (error) {console.error('獲取分類列表失敗:', error)}},// 重置表單resetTemp() {this.temp = {id: undefined,book_no: '',name: '',category_id: undefined,author: '',publish_date: undefined,price: 0,status: 1,remark: '',use_status: 0,is_second_hand: 0}},// 打開新增對話框handleCreate() {this.resetTemp()this.dialogTitle = '新增圖書'this.dialogVisible = truethis.$nextTick(() => {this.$refs['dataForm'].clearValidate()})},// 打開編輯對話框handleUpdate(row) {this.temp = Object.assign({}, row)this.dialogTitle = '編輯圖書'this.dialogVisible = truethis.$nextTick(() => {this.$refs['dataForm'].clearValidate()})},// 提交表單submitForm() {this.$refs['dataForm'].validate(async (valid) => {if (valid) {try {if (this.temp.id) {// 更新await updateBook(this.temp.id, this.temp)this.$message.success('更新成功')} else {// 新增await createBook(this.temp)this.$message.success('創建成功')}this.dialogVisible = falsethis.getList()} catch (error) {console.error('保存圖書失敗:', error)}}})},// 刪除圖書handleDelete(row) {this.$confirm('確認刪除該圖書嗎?', '提示', {type: 'warning'}).then(async () => {try {await deleteBook(row.id)this.$message.success('刪除成功')this.getList()} catch (error) {console.error('刪除圖書失敗:', error)}}).catch(() => {})},// 更新狀態async handleStatusChange(row) {try {await updateBookStatus(row.id, row.status)this.$message.success('狀態更新成功')} catch (error) {console.error('更新狀態失敗:', error)// 恢復原狀態row.status = row.status === 1 ? 0 : 1}}}
}
</script><style lang="scss" scoped>
.filter-container {padding-bottom: 10px;.filter-item {margin-right: 10px;}
}
</style>

部分后端代碼:

const BookModel = require('../models/book.model')
const Response = require('../utils/response')
const asyncHandler = require('../utils/asyncHandler')class BookController {/*** 獲取圖書列表*/getList = asyncHandler(async (req, res) => {const { name } = req.queryconst books = await BookModel.getAll({ name })res.json(Response.success(books))})/*** 獲取圖書詳情*/getDetail = asyncHandler(async (req, res) => {const { id } = req.paramsconst book = await BookModel.findById(id)if (!book) {return res.json(Response.error('圖書不存在'))}res.json(Response.success(book))})/*** 創建圖書*/create = asyncHandler(async (req, res) => {const { book_no, name, category_id, author, publish_date, price, status, remark, use_status, is_second_hand } = req.body// 驗證必填字段if (!book_no) {return res.json(Response.error('圖書編號不能為空'))}if (!name) {return res.json(Response.error('圖書名稱不能為空'))}if (!category_id) {return res.json(Response.error('圖書分類不能為空'))}if (!author) {return res.json(Response.error('作者不能為空'))}if (!publish_date) {return res.json(Response.error('出版日期不能為空'))}if (!price) {return res.json(Response.error('定價不能為空'))}const id = await BookModel.create({ book_no, name, category_id, author, publish_date, price, status, remark,use_status,is_second_hand})const book = await BookModel.findById(id)res.json(Response.success(book, '創建成功'))})/*** 更新圖書*/update = asyncHandler(async (req, res) => {const { id } = req.paramsconst { book_no, name, category_id, author, publish_date, price, status, remark, use_status, is_second_hand } = req.bodyconst book = await BookModel.update(id, { book_no, name, category_id, author, publish_date, price, status, remark,use_status,is_second_hand})res.json(Response.success(book, '更新成功'))})/*** 刪除圖書*/delete = asyncHandler(async (req, res) => {const { id } = req.paramsawait BookModel.delete(id)res.json(Response.success(null, '刪除成功'))})/*** 更新圖書狀態*/updateStatus = asyncHandler(async (req, res) => {const { id } = req.paramsconst { status } = req.bodyif (status === undefined) {return res.json(Response.error('狀態不能為空'))}const book = await BookModel.updateStatus(id, status)res.json(Response.success(book, '狀態更新成功'))})
}module.exports = new BookController()

代碼量還是很多的,畢竟是一個管理系統,由于文章字數,這里就不一一復制粘貼代碼了,如果你需要完整的項目源碼,可以去下方網站了解。
https://wwwoop.com/home/Index/projectInfo?goodsId=97&typeParam=1&subKey=0

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/86991.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/86991.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/86991.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【甲方安全視角】企業建設下的安全運營

文章目錄 一、安全運營的概念與起源二、安全運營的職責與定位三、安全運營工程師的核心能力要求四、安全運營的典型場景與應對技巧1. 明確責任劃分,避免“醫生做保姆”2. 推動機制:自下而上 vs. 自上而下3. 宣傳與內部影響力建設五、安全運營的戰略意義六、為何需要安全原因在…

03認證原理自定義認證添加認證驗證碼

目錄 大綱 一、自定義資源權限規則 二、自定義登錄界面 三、自定義登錄成功處理 四、顯示登錄失敗信息 五、自定義登錄失敗處理 六、注銷登錄 七、登錄用戶數據獲取 1. SecurityContextHolder 2. SecurityContextHolderStrategy 3. 代碼中獲取認證之后用戶數據 4. 多…

IPLOOK 2025上半年足跡回顧:連接全球,步履不停

2025年上半年&#xff0c;IPLOOK積極活躍于全球通信舞臺&#xff0c;足跡橫跨亞洲、歐洲、非洲與北美洲&#xff0c;我們圍繞5G核心網、私有網絡、云化架構等方向&#xff0c;向來自不同地區的客戶與合作伙伴展示了領先的端到端解決方案&#xff0c;深入了解各地市場需求與技術…

【Kafka】docker 中配置帶 Kerberos 認證的 Kafka 環境(全過程)

1. 準備 docker 下載鏡像 docker pull centos/systemd&#xff0c;該鏡像是基于 centos7 增加了 systemd 的功能&#xff0c;可以更方便啟動后臺服務 啟動鏡像 使用 systemd 功能需要權限&#xff0c;如果是模擬 gitlab services 就不要使用 systemd 的方式啟動 如果不使用 s…

用Python構建一個可擴展的多網盤聚合管理工具 (以阿里云盤為例)

摘要 本文旨在從開發者視角&#xff0c;探討并實踐如何構建一個命令行界面的、支持多網盤聚合管理的工具。我們將以阿里云盤為例&#xff0c;深入解析其API認證與核心操作&#xff0c;并用Python從零開始實現文件列表、重命名、分享等功能。更重要的是&#xff0c;本文將重點討…

筑牢網絡安全屏障

在數字化浪潮席卷全球的今天&#xff0c;網絡空間已成為繼陸、海、空、天之后的 “第五疆域”&#xff0c;深刻影響著國家政治、經濟、軍事等各個領域。“沒有網絡安全就沒有國家安全”&#xff0c;這句論斷精準道出了網絡安全與國家安全之間密不可分的關系。? 網絡安全關乎國…

計算機網絡(一)層

一、分層 分層的意義&#xff1a;簡化復雜性、提高靈活性、促進標準化 &#xff08;1&#xff09;法律上國際標準——OSI體系結構 &#xff08;2&#xff09;事實上的網絡標準——TCP/IP體系結構 TCP&#xff1a;運輸層的協議 IP&#xff1a;網際層的一個協議 網絡接口層&…

STM32 rs485實現中斷DMA模式收發不定長數據

在STM32F103上使用TD301D485H模塊通過USB轉485/422串口線與電腦通信 TXD (TD301D485H) -> PA2 (STM32F103)RXD (TD301D485H) -> PA3 (STM32F103)CON (TD301D485H) -> PA1 (STM32F103) 由于485是半雙工通信&#xff0c;需要在發送和接收時控制方向引腳&#xff08;CO…

DDL-8-小結

DDL 小結 DDL 小結 DDL 小結DDL - 數據庫操作DDL - 表操作 DDL - 數據庫操作 查看當前有哪些數據庫 SHOW DATABASES;新建數據庫 CREATE DATABASE 數據庫名;使用數據庫 USE 數據庫名;查詢當前數據庫 SELECT DATABASE();刪除數據庫 DROP DATABASE 數據庫名;DDL - 表操作 查看當前…

Redis 安裝使用教程

一、Redis 簡介 Redis 是一個開源&#xff08;BSD 許可&#xff09;、內存數據結構存儲系統&#xff0c;可以用作數據庫、緩存和消息中間件。支持字符串、哈希、列表、集合、有序集合等數據類型&#xff0c;廣泛應用于分布式緩存、排行榜、實時數據分析等場景。 二、下載安裝…

Go語言測試與調試:單元測試與基準測試

以下是《Go語言實戰指南》中關于 測試與調試&#xff1a;單元測試與基準測試 的詳細內容&#xff0c;涵蓋測試編寫、運行、覆蓋率分析與性能測試&#xff0c;適用于實際項目開發與性能優化階段。 一、Go 的測試體系概覽 Go 提供原生的測試工具包 testing&#xff0c;無需第三方…

數字FIR-I型濾波器設計(窗函數法)

目錄 一、實驗目的 二、實驗原理 2.1 概念辨析 2.2 代碼實現邏輯與工具函數 三、實驗內容 3.1 設計帶通濾波器&#xff08;電平組合法&#xff0c;&#xff08;理想寬帶低通-理想窄帶低通&#xff09;x窗函數&#xff09; 3.2 高通濾波器&#xff08;…

RHCSA認證題目練習一(配置網絡設置)

一. 題目 配置網絡設置 解題過程&#xff1a; 注意&#xff1a;不可以在xshell中完成&#xff0c;否則會直接斷聯 這里用圖形化解題&#xff0c;更加簡單防止命令記錯 1. 打開圖形化視圖 命令&#xff1a;nmtui 按回車確認 按回車確認 2.首先把IPv4配置 <自動> 改成 …

STL簡介+string模擬實現

STL簡介string模擬實現 1. 什么是STL2. STL的版本3. STL的六大組件4.STL的缺陷5. string5.1 C語言中的字符串5.2 1個OJ題 6.標準庫中的string類6.1 string類(了解)6.2 string類的常用接口說明1.string類對象的常見構造函數2.析構函數(~string())3.賦值函數 (operator) 6.3 stri…

golang實現一個mysql中隨機獲取cookies的API

之前用FASTAPI寫了一個隨機cookies請求的接口,現在嘗試用golang實現同樣的效果 1.編寫go代碼 package mainimport ("database/sql""encoding/json""fmt"_ "github.com/go-sql-driver/mysql""log""net/http"&quo…

[Vue2組件]三角形角標

[Vue2組件]三角形角標 <template><div class"ys-subscript" :style"svgStyle"><svg width"200" height"200" viewBox"0 0 200 200" xmlns"http://www.w3.org/2000/svg"><!-- 三角形背景 - 右…

洛谷刷題4

B4354 [GESP202506 一級] 假期閱讀 題目傳送門 B4354 難度&#xff1a;入門 很簡單的題&#xff0c;如果小A看的頁數≤這本書的頁數&#xff0c;輸出他看的頁數 否則&#xff0c;輸出這本書的頁數 AC代碼&#xff1a; #include <iostream> using namespace std; in…

【基于Echarts的地圖可視化】

<!DOCTYPE html> <html> <head><meta charset"utf-8"><title>中國牛只分布可視化</title><script src"https://cdn.jsdelivr.net/npm/echarts5.4.3/dist/echarts.min.js"></script><script src"h…

系統架構設計師備考之架構設計基礎

1.計算機系統基礎知識 1.1.計算機系統概述 計算機系統的定義與組成 計算機系統是指用于數據管理的計算機硬件、軟件及網絡組成的系統。 計算機系統可劃分為硬件和軟件兩部分。硬件由機械、電子元器件、磁介質和光介質等物理實體構成&#xff1b; 軟件是一系列按照特定順序組織…

針對華為云服務器使用率過大

從這兩張監控圖可以看出&#xff0c;服務器在大約上午 10:30 前后經歷了一次明顯的負載變化&#xff1a; 1. 圖表解讀 CPU 使用率 從凌晨到上午約 10:00 前&#xff0c;CPU 基本處于 0–2% 的閑置狀態。10:00–14:00 之間&#xff0c;CPU 利用率逐步攀升&#xff0c;多次沖擊 3…