随着技术的进步,跨平台开发已经成为了标配,在此大背景下,ASP.NET Core也应运而生。本文主要基于ASP.NET Core+Element+Sql Server开发一个校园图书管理系统为例,简述基于MVC三层架构开发的常见知识点,前三篇篇文章简单介绍了如何搭建开发框架,登录功能,主页面功能,以及书室管理,书架管理功能的实现,本篇文章继续讲解书籍管理以及借还功能相关功能的开发,仅供学习分享使用,如有不足之处,还请指正。
涉及知识点
在本示例中,应用最多的就是如何Element中提供的组件,和控制器中业务逻辑处理,涉及知识点如下所示:
- MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式,其中Controller(控制器)处理输入(写入数据库记录)。控制器Controller,是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
- Element组件库,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。可以大大提高开发效率,减少工作量。在主页面中,主要用到如下几种:
- 表单控件el-form,由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据到后台。
- 列表控件el-table,用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。主要用户显示结构化列表的数据。
- 分页控件el-pagination,当数据量过多时,使用分页分解数据。
- 弹出窗口el-dialog,在保留当前页面状态的情况下,告知用户并承载相关操作。主要用于弹出新建或编辑窗口。
- axios组件,是一个基于promise 的网络请求库,axios本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范。在本示例中,所有的前后端交互,均是通过axios库。
功能介绍
本文主要介绍书籍管理和借还管理两个功能,如下所示:
- 图书管理,主要包括书籍的检索,新增,修改,删除等基本功能,另外书籍的存放位置和书架ID相关,书架又与书室相关,所有相对比较复杂。
- 借还管理,主要根据用于输入或扫描的ISBN号,进行借阅以及归还,主要记录借阅人,借阅时间,借阅经手人,归还时间,归还经手人等信息。
图书管理
1. Book表结构
图书管理,主要是对Book表的CRUD操作,表结构如下所示:

其中BookRackId为书架ID,与BookRack表的外键。
2. Book表实体类
Book表实体类是数据表的数据映射,和数据表一一对应,如下所示:- 1 namespace CLMS.Entity
- 2 {
- 3 /// <summary>
- 4 /// 图书实体
- 5 /// </summary>
- 6 public class BookEntity
- 7 {
- 8 /// <summary>
- 9 /// 唯一标识
- 10 /// </summary>
- 11 public int Id { get; set; }
- 12
- 13 /// <summary>
- 14 /// 图书编号
- 15 /// </summary>
- 16 public string ISBN { get; set; }
- 17
- 18 /// <summary>
- 19 /// 图书名称
- 20 /// </summary>
- 21 public string Name { get; set; }
- 22
- 23 /// <summary>
- 24 /// 图书作者
- 25 /// </summary>
- 26 public string Author { get; set; }
- 27
- 28 /// <summary>
- 29 /// 图书出版社
- 30 /// </summary>
- 31 public string Publisher { get; set; }
- 32
- 33 /// <summary>
- 34 /// 出版时间
- 35 /// </summary>
- 36 public DateTime PublishDate { get; set; }
- 37
- 38 /// <summary>
- 39 /// 图书类型
- 40 /// </summary>
- 41 public string BookType { get; set; }
- 42
- 43 /// <summary>
- 44 /// 描述
- 45 /// </summary>
- 46 public string Description { get; set; }
- 47
- 48 /// <summary>
- 49 /// 书架ID
- 50 /// </summary>
- 51 public long BookRackId { get; set; }
- 52
- 53 /// <summary>
- 54 /// 创建时间
- 55 /// </summary>
- 56 public DateTime CreateTime { get; set; }
- 57
- 58 /// <summary>
- 59 /// 当前登录的账号的ID
- 60 /// </summary>
- 61 public int CreateUser { get; set; }
- 62
- 63 /// <summary>
- 64 /// 最后编辑时间
- 65 /// </summary>
- 66 public DateTime? LastEditTime { get; set; }
- 67
- 68 /// <summary>
- 69 /// 最后修改人
- 70 /// </summary>
- 71 public int LastEditUser { get; set; }
- 72 }
- 73 }
复制代码 3. 图书管理页面布局
图书管理页面主要包括对书籍的查询,新增,编辑,删除等操作,页面布局如下所示:4. 图书管理数据交互
数据交互通过JS脚本进行,书写格式和VUE2.0保持一致,在页面启动时,加载所有的书室信息,并绑定到el-table对象,所以需要在mounted函数中增加调用向服务器端发出请求,当用户新增或编辑保存时,通过axios发送请求到服务端接口。5. 图书控制器逻辑BookController
控制器主要用于响应用户的请求,与数据库交互,并返回执行的结果信息。- 1 namespace CLMS.Host.Controllers
- 2 {
- 3 public class BookController : Controller
- 4 {
- 5 private DataContext dataContext;
- 6
- 7 public BookController(DataContext context) {
- 8 dataContext = context;
- 9 }
- 10
- 11 public IActionResult Index()
- 12 {
- 13 return View();
- 14 }
- 15
- 16 /// <summary>
- 17 /// 获取符合条件的查询
- 18 /// </summary>
- 19 /// <param name="Name"></param>
- 20 /// <param name="Publisher"></param>
- 21 /// <param name="pageNum"></param>
- 22 /// <param name="pageSize"></param>
- 23 /// <returns></returns>
- 24 [HttpGet]
- 25 public PagedRequest<Book> Query(string Name, string Publisher, int pageNum, int pageSize)
- 26 {
- 27 Name = string.IsNullOrEmpty(Name) ? string.Empty : Name;
- 28 Publisher = string.IsNullOrEmpty(Publisher) ? string.Empty : Publisher;
- 29 var bookEntities = dataContext.Books.Where(r => r.Name.Contains(Name) && r.Publisher.Contains(Publisher));
- 30 var total = bookEntities.Count();
- 31 var bookDtos = bookEntities.Skip((pageNum - 1) * pageSize).Take(pageSize).Select(r => new Book() { Id = r.Id, ISBN = r.ISBN, Name = r.Name, Author = r.Author, Publisher = r.Publisher, BookType = r.BookType,BookRackId=r.BookRackId,PublishDate=r.PublishDate, CreateTime = r.CreateTime,Description=r.Description }).ToList();
- 32
- 33 //位置
- 34 var bookRackIds = bookDtos.Select(r => r.BookRackId).ToList();
- 35 var locations = dataContext.BookRacks.Where(r => bookRackIds.Contains(r.Id)).Join(dataContext.Librarys, b => b.LibraryId, l => l.Id, (b, l) => new BookRack() { Name = l.Name, SubName = l.SubName, Location = l.Location, LibraryId = b.LibraryId, Id = b.Id, Row = b.Row, Column = b.Column, Description = b.Description, CreateTime = b.CreateTime }).ToList();
- 36
- 37 bookDtos.ForEach(r => {
- 38 var location = locations.FirstOrDefault(l => l.Id == r.BookRackId);
- 39 if (location != null) {
- 40 r.LibraryName = location.Name;
- 41 r.LibrarySubName=location.SubName;
- 42 r.Row=location.Row;
- 43 r.Column=location.Column;
- 44 }
- 45 });
- 46 //
- 47 return new PagedRequest<Book>()
- 48 {
- 49 count = total,
- 50 items = bookDtos,
- 51 };
- 52 }
- 53
- 54 [Consumes("application/json")]
- 55 [HttpPost]
- 56 public Msg Add([FromBody] Book book)
- 57 {
- 58 Msg msg = new Msg();
- 59 if (book == null)
- 60 {
- 61 msg.code = 1;
- 62 msg.message = "对象为空";
- 63 return msg;
- 64 }
- 65 else
- 66 {
- 67 var userId = HttpContext.Session.GetInt32("UserId");
- 68
- 69 if (book.Id > 0)
- 70 {
- 71 //更新
- 72 var entity = dataContext.Books.Where(r => r.Id == book.Id).FirstOrDefault();
- 73 if (entity != null)
- 74 {
- 75 entity.BookRackId = book.BookRackId;
- 76 entity.Author = book.Author;
- 77 entity.Publisher = book.Publisher;
- 78 entity.Description = book.Description;
- 79 entity.BookType = book.BookType;
- 80 entity.ISBN = book.ISBN;
- 81 entity.Name = book.Name;
- 82 entity.LastEditUser = userId.GetValueOrDefault();
- 83 entity.LastEditTime = DateTime.Now;
- 84 dataContext.Books.Update(entity);
- 85 dataContext.SaveChanges();
- 86 }
- 87 else
- 88 {
- 89 msg.code = 1;
- 90 msg.message = "修改失败";
- 91 return msg;
- 92 }
- 93 }
- 94 else
- 95 {
- 96 //新增
- 97 var entity = new BookEntity()
- 98 {
- 99 BookRackId = book.BookRackId,
- 100 Author = book.Author,
- 101 Publisher = book.Publisher,
- 102 PublishDate = book.PublishDate,
- 103 Description = book.Description,
- 104 BookType = book.BookType,
- 105 ISBN = book.ISBN,
- 106 Name = book.Name,
- 107 CreateTime = DateTime.Now,
- 108 CreateUser = userId.GetValueOrDefault(),
- 109 LastEditTime = DateTime.Now,
- 110 LastEditUser = userId.GetValueOrDefault(),
- 111 };
- 112 dataContext.Books.Add(entity);
- 113 dataContext.SaveChanges();
- 114 }
- 115 msg.code = 0;
- 116 msg.message = "success";
- 117 return msg;
- 118 }
- 119 }
- 120
- 121 [Consumes("application/json")]
- 122 [HttpPost]
- 123 public Msg Delete([FromBody] Book book) {
- 124 Msg msg = new Msg();
- 125 if (book == null)
- 126 {
- 127 msg.code = 1;
- 128 msg.message = "对象为空";
- 129 return msg;
- 130 }
- 131 else
- 132 {
- 133 if (book.Id > 0)
- 134 {
- 135 var entity = dataContext.Books.Where(r => r.Id == book.Id).FirstOrDefault();
- 136 if (entity != null)
- 137 {
- 138 dataContext.Books.Remove(entity);
- 139 dataContext.SaveChanges();
- 140 msg.code = 0;
- 141 msg.message = "success";
- 142 }
- 143 else {
- 144 msg.code = 1;
- 145 msg.message = "对象不存在或已被删除";
- 146 }
- 147 }
- 148 else {
- 149
- 150 msg.code = 1;
- 151 msg.message = "对象Id小于0";
- 152 }
- 153 return msg;
- 154 }
- 155 }
- 156 }
- 157 }
复制代码 6. 图书管理功能测试
经过以上几个步骤,即可完成图书管理的基本操作,主要包括图书的查询,新增,编辑,删除,已经分页等功能,如下所示:

图书借还
1. 图书借还数据表结构
图书借还包括图书的借阅和归还,两个功能,主要记录借阅人,借阅时间,归还时间,以及经手人,数据表结构如下所示:

2. 图书借还实体类
数据表实体类和数据表一一对应,主要通过EntityFrameword与数据库进行映射。如下所示:- 1 namespace CLMS.Entity
- 2 {
- 3 /// <summary>
- 4 /// 借还记录
- 5 /// </summary>
- 6 public class CirculateEntity
- 7 {
- 8 /// <summary>
- 9 /// 唯一标识
- 10 /// </summary>
- 11 public int Id { get; set; }
- 12
- 13 /// <summary>
- 14 /// 图书标识
- 15 /// </summary>
- 16 public int BookId { get; set; }
- 17
- 18 /// <summary>
- 19 /// 是否归还
- 20 /// </summary>
- 21 public bool IsReturn { get; set; }
- 22
- 23 /// <summary>
- 24 /// 借阅人
- 25 /// </summary>
- 26 public string BorrowUser { get; set; }
- 27
- 28 /// <summary>
- 29 /// 借阅时间
- 30 /// </summary>
- 31 public DateTime BorrowTime { get; set; }
- 32
- 33 /// <summary>
- 34 /// 借阅确认人
- 35 /// </summary>
- 36 public string BorrowConfirmor { get; set; }
- 37
- 38 /// <summary>
- 39 /// 归还时间
- 40 /// </summary>
- 41 public DateTime? ReturnTime { get; set; }
- 42
- 43 /// <summary>
- 44 /// 归还确认人
- 45 /// </summary>
- 46 public string? ReturnConfirmor { get; set; }
- 47 }
- 48 }
复制代码 3. 图书借还页面布局
图书借还主要包括信息查询,借阅和归还等功能,页面布局如下所示:- 1
- 2 <template>
- 3 <el-breadcrumb separator-class="el-icon-arrow-right">
- 4 <el-breadcrumb-item>图书管理</el-breadcrumb-item>
- 5 <el-breadcrumb-item>图书借阅及归还</el-breadcrumb-item>
- 6 </el-breadcrumb>
- 7 <el-form :inline="true" :model="queryCondition" class="demo-form-inline" style="margin-top: 10px; border: solid;border-width: 1px;border-color: #ebeef5;padding: 10px;">
- 8 <el-form-item label="书籍名称">
- 9 <el-input v-model="queryCondition.Name" placeholder="书籍名称"></el-input>
- 10 </el-form-item>
- 11 <el-form-item>
- 12 <el-button type="primary" v-on:click="handleQuery">查询</el-button>
- 13 </el-form-item>
- 14 <el-form-item>
- 15 <el-button type="primary" v-on:click="handleBorrow">借阅</el-button>
- 16 </el-form-item>
- 17 <el-form-item>
- 18 <el-button type="primary" v-on:click="handleReturn">归还</el-button>
- 19 </el-form-item>
- 20 </el-form>
- 21 <el-table :data="tableData" style="width: 100%" border :default-sort="{prop: 'BorrowTime', order: 'descending'}">
- 22 <el-table-column prop="Name" label="书籍名称" sortable ></el-table-column>
- 23 <el-table-column prop="ISBN" label="ISBN" sortable ></el-table-column>
- 24 <el-table-column prop="BorrowUser" label="借阅人" sortable ></el-table-column>
- 25 <el-table-column prop="BorrowTime" label="借阅时间" sortable ></el-table-column>
- 26 <el-table-column prop="BorrowConfirmor" label="借阅经手人" sortable ></el-table-column>
- 27 <el-table-column prop="IsReturn" label="是否归还" sortable ></el-table-column>
- 28 <el-table-column prop="ReturnTime" label="归还时间" sortable ></el-table-column>
- 29 <el-table-column prop="ReturnConfirmor" label="归还经手人" sortable ></el-table-column>
- 30 </el-table>
- 31 <el-pagination background layout="prev, pager, next" :page-size="pageSize" :current-page="currentPage" :total="total" style="margin-top:10px;" v-on:current-change="handlePageChanged" v-on:prev-click="handlePrevClick" v-on:next-click="handleNextClick"></el-pagination>
- 32 <el-dialog title="借阅信息" :visible.sync="dialogFormBorrowVisible">
- 33 <el-form :model="borrowForm">
- 34 <el-form-item label="ISBN" :label-width="formLabelWidth">
- 35 <el-input v-model="borrowForm.ISBN" autocomplete="off"></el-input>
- 36 </el-form-item>
- 37 <el-form-item label="书籍名称" :label-width="formLabelWidth">
- 38 <el-input v-model="borrowForm.Name" autocomplete="off"></el-input>
- 39 </el-form-item>
- 40 <el-form-item label="借阅人" :label-width="formLabelWidth">
- 41 <el-input v-model="borrowForm.BorrowUser" autocomplete="off"></el-input>
- 42 </el-form-item>
- 43 </el-form>
- 44
- 45 <el-button v-on:click="dialogFormBorrowVisible = false">取 消</el-button>
- 46 <el-button type="primary" v-on:click="handleSaveBorrow">确 定</el-button>
- 47
- 48 </el-dialog>
- 49 <el-dialog title="归还信息" :visible.sync="dialogFormReturnVisible">
- 50 <el-form :model="returnForm">
- 51 <el-form-item label="ISBN" :label-width="formLabelWidth">
- 52 <el-input v-model="returnForm.ISBN" autocomplete="off"></el-input>
- 53 </el-form-item>
- 54 <el-form-item label="书籍名称" :label-width="formLabelWidth">
- 55 <el-input v-model="returnForm.Name" autocomplete="off"></el-input>
- 56 </el-form-item>
- 57 </el-form>
- 58
- 59 <el-button v-on:click="dialogFormReturnVisible = false">取 消</el-button>
- 60 <el-button type="primary" v-on:click="handleSaveReturn">确 定</el-button>
- 61
- 62 </el-dialog>
- 63 </template>
- 64
复制代码 4. 图书借还数据交互
数据交互通过JS脚本进行,书写格式和VUE2.0保持一致,在页面启动时,加载所有的图书借还信息,并绑定到el-table对象,所以需要在mounted函数中增加调用向服务器端发出请求,当用户借阅或归还保存时,通过axios发送请求到服务端接口。5. 图书借还控制器CirculateController
控制器主要用于响应用户的请求,与数据库交互,并返回执行的结果信息。- 1 namespace CLMS.Host.Controllers
- 2 {
- 3 /// <summary>
- 4 /// 借还管理
- 5 /// </summary>
- 6 public class CirculateController : Controller
- 7 {
- 8 private DataContext dataContext;
- 9
- 10 public CirculateController(DataContext context)
- 11 {
- 12 dataContext = context;
- 13 }
- 14
- 15 public IActionResult Index()
- 16 {
- 17 return View();
- 18 }
- 19
- 20 [HttpGet]
- 21 public PagedRequest<Circulate> Query(string Name, int pageNum, int pageSize)
- 22 {
- 23 Name = string.IsNullOrEmpty(Name) ? string.Empty : Name;
- 24 var dtos = dataContext.Circulates.Join(dataContext.Books, c => c.BookId, b => b.Id, (c, b) => new Circulate()
- 25 {
- 26 Id = c.Id,
- 27 Name = b.Name,
- 28 BookId = c.BookId,
- 29 BorrowConfirmor = c.BorrowConfirmor,
- 30 BorrowTime = c.BorrowTime,
- 31 BorrowUser = c.BorrowUser,
- 32 ISBN = b.ISBN,
- 33 IsReturn = c.IsReturn,
- 34 ReturnConfirmor = c.ReturnConfirmor,
- 35 ReturnTime = c.ReturnTime,
- 36 }).Where(r=>r.Name.Contains(Name));
- 37 var total = dtos.Count();
- 38 var dtos2 = dtos.Skip((pageNum - 1) * pageSize).Take(pageSize).ToList();
- 39 //
- 40 return new PagedRequest<Circulate>()
- 41 {
- 42 count = total,
- 43 items = dtos2,
- 44 };
- 45 }
- 46
- 47 [Consumes("application/json")]
- 48 [HttpPost]
- 49 public Msg Borrow([FromBody]Borrow borrow) {
- 50 Msg msg = new Msg();
- 51 if (borrow == null || string.IsNullOrEmpty(borrow.ISBN))
- 52 {
- 53 msg.code = 1;
- 54 msg.message = "书籍为空";
- 55 return msg;
- 56 }
- 57 var book = dataContext.Books.FirstOrDefault(r => r.ISBN == borrow.ISBN);
- 58 if (book == null)
- 59 {
- 60 msg.code = 1;
- 61 msg.message = "ISBN有误";
- 62 return msg;
- 63 }
- 64 var entity = dataContext.Circulates.FirstOrDefault(r => r.BookId == book.Id && r.IsReturn == false);
- 65 if (entity != null)
- 66 {
- 67 msg.code = 1;
- 68 msg.message = "书籍已被借阅";
- 69 return msg;
- 70 }
- 71 var userId = HttpContext.Session.GetInt32("UserId");
- 72 if (userId < 0) {
- 73 msg.code = 1;
- 74 msg.message = "尚未登录";
- 75 return msg;
- 76 }
- 77 var borrorConfirmor = dataContext.Users.FirstOrDefault(r => r.Id == userId)?.NickName;
- 78 var entity2 = new CirculateEntity()
- 79 {
- 80 Id = 0,
- 81 BookId = book.Id,
- 82 IsReturn = false,
- 83 BorrowTime = DateTime.Now,
- 84 BorrowUser=borrow.BorrowUser,
- 85 BorrowConfirmor= borrorConfirmor,
- 86 };
- 87 this.dataContext.Circulates.Add(entity2);
- 88 this.dataContext.SaveChanges();
- 89 msg.code = 0;
- 90 msg.message = "success";
- 91 return msg;
- 92 }
- 93
- 94 /// <summary>
- 95 /// 归还
- 96 /// </summary>
- 97 /// <param name="returns"></param>
- 98 /// <returns></returns>
- 99 [Consumes("application/json")]
- 100 [HttpPost]
- 101 public Msg Return([FromBody] Return returns) {
- 102 Msg msg = new Msg();
- 103 if (returns == null || string.IsNullOrEmpty(returns.ISBN))
- 104 {
- 105 msg.code = 1;
- 106 msg.message = "书籍为空";
- 107 return msg;
- 108 }
- 109 var book = dataContext.Books.FirstOrDefault(r => r.ISBN == returns.ISBN);
- 110 if (book == null)
- 111 {
- 112 msg.code = 1;
- 113 msg.message = "ISBN有误";
- 114 return msg;
- 115 }
- 116 var userId = HttpContext.Session.GetInt32("UserId");
- 117 if (userId < 0)
- 118 {
- 119 msg.code = 1;
- 120 msg.message = "尚未登录";
- 121 return msg;
- 122 }
- 123 var returnConfirmor = dataContext.Users.FirstOrDefault(r => r.Id == userId)?.NickName;
- 124 var entity = dataContext.Circulates.FirstOrDefault(r => r.BookId == book.Id && r.IsReturn == false);
- 125 if (entity != null)
- 126 {
- 127 entity.IsReturn = true;
- 128 entity.ReturnTime = DateTime.Now;
- 129 entity.ReturnConfirmor=returnConfirmor;
- 130 dataContext.Circulates.Update(entity);
- 131 dataContext.SaveChanges();
- 132 msg.code = 0;
- 133 msg.message = "success";
- 134 }
- 135 else {
- 136 msg.code = 1;
- 137 msg.message = "书籍已归还";
- 138 }
- 139 return msg;
- 140 }
- 141 }
- 142 }
复制代码 6. 图书借还功能测试
图书借还主要包括借阅和归还,如下所示:

以上就是校园图书管理系统的图书管理及图书借还功能实现,功能正在开发完善中,后续功能再继续介绍。旨在抛砖引玉,一起学习,共同进步。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |