scala借阅图书保存记录(三)

news2025/4/27 10:45:33

BookDAO

package org.app
package dao

import models.BookModel

import scala.collection.mutable.ListBuffer

//图书,数据操作
class BookDAO {
  //加载图书,从文件中读入
  def loadBooks(): ListBuffer[BookModel] = {
    val books = new ListBuffer[BookModel]()
    val source =scala.io.Source.fromFile("books.txt")
    for (line <- source.getLines()){
      val Array(id, name, author,available) = line.split(",")
      //
       books += BookModel(id.toInt, name, author, available.toBoolean)
    }
    //关闭连接
    source.close()
    books
  }

//保存图书,将图书写入文件
def saveBooks(books:ListBuffer[BookModel]):Unilt ={
	val writer = new java.io.PrintWriter(new java.io.File("books.txt"))
	for(book <- books){
	writer.println(book.id + "," + book.name + "," + book.author + "," + book.available)
}
writer.close()
}
}
BorrowRecordDAO
package org.app
package dao

import org.app.models.BorrowRecordModel

import scala.collection.mutable.ListBuffer
import scala.io.Source

class BorrowRecordDAO{
  // 读出借阅记录
  def loadBorrowRecords(): ListBuffer[BorrowRecordModel] = {
    val borrowRecords = ListBuffer[BorrowRecordModel]()
    val lines = Source.fromFile("borrow_records.txt")
    for(line <- lines.getLines()){
      val parts = line.split(",")

      borrowRecords += BorrowRecordModel(
        parts(0),
        parts(1).toInt,
        parts(2),
        parts(3),
        if(parts.length>4)Some(parts(4))else None
      )
      //      val Array(userName,bookID,bookName,borrowDate,returnDate) = line.split(",")
      //      borrowRecords += BorrowRecordModel(userName,bookID.toInt,bookName,borrowDate,Some(returnDate))
    }
    borrowRecords
  }

  // 写入借阅记录
  def saveBorrowRecords(records: ListBuffer[BorrowRecordModel]): Unit = {
    val writer = new java.io.PrintWriter("borrow_records.txt")
    for(record <- records){
      writer.println(record.userName+","+record.bookID+","+record.bookName+","+record.borrowDate+","+record.returnDate.getOrElse(""))
    }
    writer.close()
  }
}
package org.app
package dao

import models.UserModel

import scala.collection.mutable.ListBuffer

class UserDAO {


  //加载所有的用户
  def loadUsers():List[UserModel]={
    val books = new ListBuffer[UserModel]()
    val source = scala.io.Source.fromFile("books.txt")
    for (line <- source.getLines()) {
      val Array(username,password,role) = line.split(",")
      //
      books += UserModel(username,password,role)
    }
    //关闭连接
    source.close()
    users
  }
}

BookModel

package org.app
package models

//图书类
//id,书名,作者,available:是否外借
case class BookModel(id:Int,name:String,author:String,available:Boolean) {
  override def toString:String = {
    val availableStr = if(available) "可外借" else "已借出"
    s"编号:$id \t $name \t $author,$availableStr"
  }

}
BorrowRecordModel
package org.app
package models

//借阅记录类
case class BorrowRecordModel (
  userName: String,   //借书人
  bookID:Int,          //书籍ID
  bookName: String,      //书籍名称
  borrowDate: String,      //借书日期
  returnDate: Option[String] = None       //还书日期
                             )

UsreModel

package org.app
package models

case class UserModel (
                     username:String,
                       password:String,
                     role:String //普通用户
                     ){


}

BookService

package org.app
package service

import org.app.dao.{BookDAO, BorrowRecordDAO}
import org.app.models.{BookModel, BorrowRecordModel}

import java.time.{LocalDate, LocalDateTime}
import scala.collection.mutable.ListBuffer



//图书业务逻辑层
class BookService {
    private val bookDAO = new BookDAO()
    private val borrowRecordDAO = new BorrowRecordDAO()
  //查询所有图书
//  def searchBooks(query: String): List[Book对象] = {
def searchBooks(query: String): ListBuffer[BookModel] = {
  //从文本文件中读取书本信息,并保存列表中,返回

   val books =  bookDAO.loadBooks()
query match {
  case "" => books
  case _ => books.filter(b =>b.name.contains(query) || b.author.contains(query))//有条件,就过滤
}
}
//普通用户,借阅图书
def borrowBook(username:String,bookId:Int):Boolean ={
//service//1,根据图书的·ID查询图书,判断图书书否存
 val books =  bookDAO.loadBooks()
  val records =borrowRecordDAO.loadBorrowRecords()
 val book = books.find(b =>b.id == bookId)
 if(book.nonEmpty){
 val b = book.get
//2.判断图书是否被借出
if(book.get.available){
  val b = book.get
//3.借阅图书
//更新这本书的状态
val b.available = false
//把更新之后的图书信息写回txt文件中
bookDAO.saveBooks(books)
//TODO 添加一条借书的记录
  //读出当前全部记录
  //添加一条
  records += BorrowRecordModel(username,b.id,b.name,LocalDateTime.now().toString)
  //写回文件
borrowRecordDAO.saveBorrowRecords(records)
println("借阅成功")
true
}else{
println("这本书被借走了")
 false
}
}else {
   false
 }
}
}

UserService

package org.app
package service

import dao.UserDAO

import org.app.models.UserModel

class UserService {
  private val userDAO = new UserDAO()
  //身份校验
  def authenticateUser(username:String,password:String):Option[UserModel]={
    //根据用户名和密码查询,是否符合要求
    val users = userDAO.loadUsers()
    users.find(user=>user.username==username&&user.password==password)
  }

}

library

package org.app
package ui

import org.app.models.UserModel
import org.app.service.{BookService, UserService}

import scala.io.StdIn
import scala.io.StdIn.readLine

class library {

  private val BookService = new BookService()
  private val UserService = new UserService()
  // 显示游客的菜单
  def showVisitorMenu(): Unit = {
    var running = true
    while (running) {
      println("欢迎来到我的图书管理系统, 请选择")
      println("1. 查看所有图书")
      println("2. 查询图书")
      println("3. 登录")
      println("4. 离开")

      // 获取用户的操作
      val choice = StdIn.readLine().trim
      choice match {
        case "1" =>
          // 调用业务逻辑层的方法
          val results = BookService.searchBooks("")
          if(results.nonEmpty){
            results.foreach(println)
          } else {
            println("没有找到图书")
          }
        case "2" =>
          // 提示用户输入查询关键字
          val query = readLine("请输入查询关键字(书名,作者):").trim
          // 根据关键字去查询图书列表,找到满足条件的书
          val results = BookService.searchBooks(query)
          // 显示出来
          if(results.nonEmpty){
            println("=======查询图书的结果:=======")
            results.foreach(println)
          } else {
            println("没有找到图书")
          }
        case "3" =>
          println("请输入用户名:")
          val username = StdIn.readLine().trim
          println("请输入密码:")
          val password = StdIn.readLine().trim
          // 调用Service的方法,进行登录
          val userOpt = UserService.authenticateUser(username, password)
          if(userOpt.isEmpty){
            println("用户名或密码错误")
          } else {
            println("登录成功")
            // 登录成功,显示登录用户的菜单
            val user = userOpt.get
            user.role match {
              case "管理员" => showAdminMenu(user)
              case "普通用户" => showUserMenu(user)
            }
          }
        case "4" =>
          running = false
          println("感谢你的使用,下次再见")
        case _ => println("无效的选择")
      }
    }
  }

  // 显示管理员的菜单
  def showAdminMenu(user:UserModel): Unit = {
    var running = true
    while (running) {
      println(s"欢迎管理员:${user.username},来到我的图书管理系统, 请选择")
      println("1. 添加图书")
      println("2. 查询图书")
      println("4. 退出")

      // 获取用户的操作
      val choice = StdIn.readLine().trim
      choice match {
        case "1" => println("添加图书")
        case "2" => println("查询图书")
        case "4" => running = false
        case _ => println("无效的选择")
      }
    }
  }
  // 显示登录用户的菜单
  def showUserMenu(user:UserModel): Unit = {
    var running = true
    while (running) {
      println(s"欢迎用户:${user.username},来到我的图书管理系统, 请选择")
      println("1. 借阅图书")
      println("2. 查询借阅图书")
      println("3. 查询图书")
      println("4. 退出")

      // 获取用户的操作
      val choice = StdIn.readLine().trim
      choice match {
        case "1" =>
          // UI: 提示用户输入图书的ID。校验:判断是不是整数
          try {
            val id = readLine("请输入图书的ID:").toInt
            BookService.borrowBook(user.username, id)
          } catch {
            case e:Exception =>
              println(e)
              println("输入的图书ID无效")
          }

        case "2" =>
          println("查询借阅图书")
          // 在BookService中实现根据用户名去查询借阅图书
          val borrowRecords = BookService.queryBorrowRecords(user.username)
          //判断是否为空
          if(borrowRecords.isEmpty){
            println("没有借阅记录")
          }else{
            //遍历借阅记录
            for(record <- borrowRecords){
              println(record)
              val returnDate = record.returnDate.getOrElse("未归还")
              println(s"书名:${record.bookName}借阅日期:${record.borrowDate},归还日期:$returnDate")
            }
          }
        case "4" => running = false
        case _ => println("无效的选择")
      }
    }
  }

  def showMenu(): Unit = {
    showVisitorMenu()
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2265414.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

无标记动作捕捉系统如何赋能体育运动分析,推动体育科学发展?

随着技术的不断发展与社会的需要&#xff0c;健康、科学运动成为了大众关注的一个热词。在韩国首尔的中央大学&#xff0c;其生物运动临床康复实验室和运动训练中心就致力于通过生物力学分析来研究与运动相关的伤害&#xff0c;并通过定制科学的训练计划来帮助运动员改进他们的…

Unittest02|TestSuite、TestRunner、HTMLTestRunner、处理excel表数据、邮件接收测试结果

目录 八、测试套件TestSuite和测试运行器TestRunner 1、基本概念 2、创建和使用测试套件 3、 自动发现测试用例、创建测试套件、运行测试 4、生成html的测试报告&#xff1a;HTMLTestRunner 1️⃣导入HTMLTestRunner模块 2️⃣运行测试用例并生成html文件 九、unittest…

[搜广推]王树森推荐系统笔记——曝光过滤 Bloom Filter

曝光过滤 & Bloom Filter 曝光过滤主要在召回阶段做&#xff0c;主要方法是Bloom Filter 曝光过滤问题 -如果用户看过某个物品&#xff0c;则不再把该物品曝光给该用户。 - 原因是重复曝光同一个物品会损害用户体验 - 但长视频通常没有曝光过滤&#xff08;youtube&…

JS CSS HTML 的代码如何快速封装

我们为什么要封装代码&#xff0c;是因为封装后的代码&#xff0c;会显得非常美观&#xff0c;减少代码的复用&#xff0c;方便我们更好的去维护代码&#xff0c;不用一个一个页面的去找去改&#xff0c;直接封装好的代码里面去改就可以了 目录 1.html代码封装 2.CSS代码封装 …

acme ssl证书自动续签 nginx

参考 github 官方操作 &#xff0c;acme操作说明 说下我的操作 安装 acme.sh curl https://get.acme.sh | sh source ~/.bashrc 2.注册 acme.sh --register-account -m 123qq.com 如果你在配置 acme.sh 时选择了其他 CA&#xff08;如 Let’s Encrypt&#xff09;&#xff…

【专题】2024抖音电商母婴行业分析报告汇总PDF洞察(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p38651 在数字化浪潮的席卷下&#xff0c;抖音电商母婴行业正经历着深刻变革。当下&#xff0c;年轻一代父母崛起&#xff0c;特别是 24 至 30 岁以及 18 至 23 岁的群体成为抖音母婴行业兴趣人群的主力军。他们带来全新育儿理念&…

设计模式之 abstract factory

适用场景 一个系统要独立于它的产品的创建、组合和表示时。一个系统要由多个产品系列中的一个来配置时。当你要强调一系列相关的产品对象的设计以便进行联合使用时。当你提供一个产品类库&#xff0c;而只想显示它们的接口而不是实现时 架构演示 首先client这个东西可以接触到…

UE5仿漫威争锋灵蝶冲刺技能

这两天玩了一下漫威争锋Marvel Rivals&#xff0c;发现是UE5做的&#xff0c;对里面一些角色技能挺感兴趣的&#xff0c;想简单复刻一下技能功能&#xff0c;顺便复习一下学过的知识 首先把摄像机设置调整一下 CameraBoom里搜索lag 把摄像机延迟关掉 &#xff0c;这样摄像机就…

尼伽OLED赋能中国移动,打造移动AI数字人透明显示屏

随着人工智能和显示技术的不断进步&#xff0c;中国移动紧跟科技潮流&#xff0c;将移动AI数字人技术与透明屏完美结合&#xff0c;为用户带来了前所未有的智能交互体验。基于中国移动九天大模型生成的数字人小天&#xff0c;便是这一创新技术的典型代表。它不仅能够实现定点播…

goview——vue3+vite——数据大屏配置系统

低代码数据大屏配置系统&#xff1a; 数据来源是可以动态api配置的&#xff1a; 配置上面的api接口后&#xff0c;在数据过滤中进行数据格式的转化。 以上内容&#xff0c;来源于https://gitee.com/dromara/go-view/tree/master-fetch/ 后端代码如下&#xff0c;需要更改…

GitLab安装|备份数据|迁移数据及使用教程

作者&#xff1a; 宋发元 最后更新时间&#xff1a;2024-12-24 GitLab安装及使用教程 官方教程 https://docs.gitlab.com/ee/install/docker.html Docker安装GitLab 宿主机创建容器持久化目录卷 mkdir -p /docker/gitlab/{config,data,logs}拉取GitLab镜像 docker pull gi…

JavaWeb Servlet的反射优化、Dispatcher优化、视图(重定向)优化、方法参数值获取优化

目录 1. 背景2. 实现2.1 pom.xml2.2 FruitController.java2.3 DispatcherServlet.java2.4 applicationContext.xml 3. 测试 1. 背景 前面我们做了Servlet的一个案例。但是存在很多问题&#xff0c;现在我们要做优化&#xff0c;优化的步骤如下&#xff1a; 每个Fruit请求都需…

selenium执行js

JS知识 获取元素 document.getElement 移除属性&#xff1a;removeAttribute("xx") 窗口移动&#xff1a;window.scrollTo(0, document.body.scrollHeight)方法 drivier.execute_script(js)场景&#xff1a; 日期选择框&#xff0c;不能输入&#xff0c;只能设置…

《信管通低代码信息管理系统开发平台》Linux环境安装说明

1 简介 信管通低代码信息管理系统应用平台提供多环境软件产品开发服务&#xff0c;包括单机、局域网和互联网。我们专注于适用国产硬件和操作系统应用软件开发应用。为事业单位和企业提供行业软件定制开发&#xff0c;满足其独特需求。无论是简单的应用还是复杂的系统&#xff…

static 和const的作用面试常问

点击上方"蓝字"关注我们 01、static 关键字 >>> 1. 局部变量 作用:将变量的生命周期延续到程序的整个运行期间,而不仅仅是它所在的函数调用期间。 void func() {static int count = 0; // 只会初始化一次 count++; printf("%d\n", count)…

VS2022 中的 /MT /MTd /MD /MDd 选项

我们有时编译时,需要配置这个 运行库,指定C/C++运行时库的链接方式。 如下图 那么这些选项的含义是什么? /MT:静态链接多线程库 /MT选项代表“Multi-threaded Static”,即多线程静态库。选择此选项时,编译器会从运行时库中选择多线程静态连接库来解释程序中的代码,…

掌握 Ansys ACP 中的参考方向:简化复杂的复合材料设计

概括 在复合材料分析领域&#xff0c;精度至关重要&#xff0c;尤其是在定义纤维方向和铺层时。Ansys ACP&#xff08;Ansys Composite PrepPost&#xff09;提供了强大的工具来建立参考方向&#xff0c;这是实现精确结构模拟的关键步骤。在本博客中&#xff0c;我们将揭开在 …

金仓数据库安装-Kingbase v9-centos

在很多年前有个项目用的金仓数据库&#xff0c;上线稳定后就没在这个项目了&#xff0c;只有公司的开发环境还在维护&#xff0c;已经好多年没有安装过了&#xff0c;重温一下金仓数据库安装&#xff0c;体验一下最新版本&#xff0c;也做一个新版本的试验环境&#xff1b; 一、…

什么是 DevOps 自动化?

DevOps 自动化是一种现代软件开发方法&#xff0c;它使用工具和流程来自动化任务并简化工作流程。它将开发人员、IT 运营和安全团队聚集在一起&#xff0c;帮助他们有效协作并交付可靠的软件。借助 DevOps 自动化&#xff0c;组织能够处理重复性任务、优化流程并更快地将应用程…

Windows中运行Linux(WSL)

Windows Subsystem for Linux&#xff08;WSL&#xff09;是一个在Windows 10和更高版本上运行Linux二进制可执行文件&#xff08;ELF格式&#xff09;的兼容层。它允许你在Windows上直接运行Linux环境&#xff0c;包括大多数命令行工具、实用程序和应用程序&#xff0c;无需修…