Scala图书管理系统

Scala 复制代码
package org.app
package dao

import org.app.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()){
      println(line)
      val Array(id, name, author, available) = line.split(",")
      //实例化一本书,保存到List
      books += BookModel(id.toInt, name, author, available.toBoolean)
    }
    //关闭连接
    source.close()
    books
  }


  //保存图书,将图书写入文件
  def saveBooks(books: ListBuffer[BookModel]): Unit = {
    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()
  }
}
Scala 复制代码
package org.app
package dao

import 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
      )
    }
    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()
  }
}
Scala 复制代码
package org.app
package dao

import models.UserModel

import scala.collection.mutable.ListBuffer

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

  //保存用户,将用户列表写入文件
  def saveUsers(users: ListBuffer[UserModel]): Unit = {
    val writer = new java.io.PrintWriter(new java.io.File("users.txt"))
    for (user <- users) {
      writer.println(user.username + "," + user.password + "," + user.role)
    }
    writer.close()
  }
}
Scala 复制代码
package org.app
package models

//借阅记录类
case class BorrowRecordModel (
                             userName:String, // 借书人
                             bookID:Int, // 书ID
                             bookName:String, // 书名
                             borrowDate:String, // 借书日期
                             var returnDate:Option[String] = None // 归还日期
                             )
Scala 复制代码
package org.app
package models

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

}
Scala 复制代码
package org.app
package service

import models.{BookModel, BorrowRecordModel}

import org.app.dao.{BookDAO, BorrowRecordDAO}

import java.time.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 = {
    // (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 (b.available) {
        // (3)借阅图书 更新这本书的状态
        b.available = false
        //把更新之后的图书的信息写回txt文件
        bookDAO.saveBooks(books)
        //添加一条借阅记录
        records += BorrowRecordModel(username, b.id, b.name, LocalDateTime.now().toString)
        //写借阅记录回文件
        borrowRecordDAO.saveBorrowRecords(records)
        println("借阅成功.已保存借阅记录!")
        true
      } else {
        println("这本书被借走了")
        false
      }
    } else {
      println("没有找到这本书")
      false
    }
  }

  // 普通用户,查询自己的借阅记录
  def queryBorrowedBooks(username: String): ListBuffer[BorrowRecordModel] = {
    //    1.把所有的记录全部读出来
    val records = borrowRecordDAO.loadBorrowRecords()
    //    2.过滤出当前用户的借阅记录
    records.filter(r => r.userName == username)
  }

  // 普通用户.归还自己借的某一本书
  def returnBook(username: String, bookId: Int): Boolean = {
    // 1.确定这本书是他本人借的并处于没有归还的状态
    queryBorrowedBooks(username).find(r => r.bookID == bookId && r.returnDate.isEmpty) match {
      case Some(record) =>
        // 2.更新书的状态
        // 2.1 加载全部的书
        val books = bookDAO.loadBooks()
        // 2.2 选择当前这本书
        val b = books.find(_.id == bookId).get
        b.available = true
        // 2.3 把更新之后的状态写回.txt文件
        bookDAO.saveBooks(books)
        // 3.更新借阅记录的状态
        //        3.1 加载全部的借阅记录
        val records = borrowRecordDAO.loadBorrowRecords()
        //        3.2 找到当前这本书的借阅记录 bookID,userName,returnDate = None
        val r = records.find(r => r.bookID == bookId && r.userName == username && r.returnDate.isEmpty).get
        r.returnDate = Some(LocalDateTime.now().toString)
        //        3.3 把更新之后的状态写回.txt文件
        borrowRecordDAO.saveBorrowRecords(records)
        true
      case None => false
    }
  }

  // 添加图书
  def addBook(book: BookModel): Unit = {
    // 1. 生成一个book ID
    // 查询所有图书. 找到最大的ID,+1
    var id = 1
    val books = bookDAO.loadBooks()
    if(books.nonEmpty){
      id = books.map(_.id).max + 1
    }
    // 2. 更新ID
    val newBook = book.copy(id = id)
    // 3. 把新的图书添加到books
    books += newBook
    // 4.写回到.txt中
    bookDAO.saveBooks(books)
  }
}
Scala 复制代码
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)
  }

  // 添加用户
  def addUser(username: String): Boolean = {
    // 1.检查用户名是否已经存在
    val users = userDAO.loadUsers()
    val user = users.find(_.username == username)
    if (user.isEmpty) {
      // 可以继续添加
      // 2.添加
      // 2.1读出所有的用户
      // 2.2添加新的用户.设置用户密码:123.类型:普通用户
      users += UserModel(username, "123", "普通用户")
      // 2.3保存到文件中
      userDAO.saveUsers(users)
      true
    }else{
      false
    }
  }
}
Scala 复制代码
package org.app
package ui

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

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

class LibrarayPresentation {

  private val BookService = new BookService()
  private val UserService = new UserService()

  // 辅助方法. 输入图书的信息. 返回一个BookModel对象
  private def inputBookInfo(): BookModel = {
    println("请输入图书名称:")
    val name = readLine().trim
    println("请输入图书作者:")
    val author = readLine().trim
    println("请输入图书是否可以外借(true/false):")
    val available = StdIn.readBoolean()
    // 初始设置编号为0
    BookModel(0, name, author, available)
  }

  //显示游客的菜单
  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" =>
          println("查看所有图书")
          // TODO 查看所有图书
          //调用业务逻辑层的方法
          val results = BookService.searchBooks("")
          if (results.nonEmpty) {
            results.foreach(println)
          } else {
            println("没有找到图书")
          }
        case "2" => println("查询图书")
          //提示用户输入查询关键字
          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("3.添加用户")
      println("4.退出")

      //获取用户的操作
      val choice = StdIn.readLine().trim
      choice match {
        case "1" =>
          // 1.获取图书信息-书名.作者.状态
          val book = inputBookInfo()
          println(book)
          // 2.调用service层的方法. 做添加到books.txt中操作
          BookService.addBook(book)
          println(s"图书《${book.name}》添加成功")
        case "2" => println("2.查询图书")
        case "3" =>
        // 1.获取用户信息-用户名
        val username = StdIn.readLine("请输入用户名:")
          // 2.调用service层的方法. 做添加到users.txt中操作
          if(UserService.addUser(username)){
            println("用户添加成功")
          }else{
            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" =>
          // 在BookService中实现根据用户名去查询借阅图书的方法
          val borrowRecords = BookService.queryBorrowedBooks(user.username)
          // 判断是否为空
          if (borrowRecords.isEmpty) {
            println("没有借阅记录")
          } else {
            //遍历借阅记录
            println("查询结果.一共借了?本.换了?本.?本未归还")
            for (record <- borrowRecords) {
              val returnDate = record.returnDate.getOrElse("未归还")
              println(s"书名:${record.bookName} 借阅日期:${record.borrowDate} 归还日期:$returnDate")
            }
          }
        case "3" =>
          try {
            val id = readLine("请输入要归还的图书ID:").toInt
            if (BookService.returnBook(user.username, id)) {
              println("归还图书成功")
            } else {
              println("归还图书失败")
            }
          } catch {
            case e: Exception =>
              println(e)
              println("输入的图书ID无效")
          }

        case "4" => running = false
        case _ => println("无效的选择")
      }
    }
  }

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

演示

结果如下:

相关推荐
风象南几秒前
SpringBoot实现数据库读写分离的3种方案
java·spring boot·后端
lzj20141 分钟前
DataPermissionInterceptor源码解读
后端
ChinaRainbowSea16 分钟前
3. RabbitMQ 的(Hello World) 和 RabbitMQ 的(Work Queues)工作队列
java·分布式·后端·rabbitmq·ruby·java-rabbitmq
雾月5517 分钟前
LeetCode 914 卡牌分组
java·开发语言·算法·leetcode·职场和发展
Y.O.U..28 分钟前
今日八股——C++
开发语言·c++·面试
dleei31 分钟前
MySql安装及SQL语句
数据库·后端·mysql
weixin_3077791336 分钟前
使用C#实现从Hive的CREATE TABLE语句中提取分区字段名和数据类型
开发语言·数据仓库·hive·c#
Xiaok10181 小时前
解决 Hugging Face SentenceTransformer 下载失败的完整指南:ProxyError、SSLError与手动下载方案
开发语言·神经网络·php
CryptoPP1 小时前
springboot 对接马来西亚数据源API等多个国家的数据源
spring boot·后端·python·金融·区块链
绿草在线1 小时前
Mock.js虚拟接口
开发语言·javascript·ecmascript