# 簡易圖書資訊系統 **[Github](https://github.com/little-air-1019/Java-Computer-Programming/tree/main/%E7%B0%A1%E6%98%93%E5%9C%96%E6%9B%B8%E8%B3%87%E8%A8%8A%E7%B3%BB%E7%B5%B1)** ## 系統架構 ### 館員登入與登出 * 館員有自己的姓名與編號,所有授權成為館員身分的人都必須使用帳號與密碼登入,才能使用館藏登錄、借書證註冊、借閱、歸還等功能。 * 如果使用者選擇 1、2、3、4 或 5,就必須印出登入畫面,輸入正確的帳號密碼後,印出「嗨(館員姓名), 歡迎登入!」,接著直接印出原本選擇的功能畫面。 * 如果輸入錯誤,就必須印出錯誤訊息,並印出「是否重新輸入? Y/N」,若使用者輸入 Y,則重新 印出訊息輸入畫面讓使用者輸入帳號密碼,輸入 N 則回到系統首頁。 * 設定三組虛擬館員帳號密碼為 | 編號 | 姓名 | 帳號 | 密碼 | | ---- | ---- | ---- | ---- | | 1 | Adam | FarAwayLIB | SoFar1111 | | 2 | Eva | FarFarAwayLIB | SoFar2222 | | 3 | Helen | FarFarFarAwayLIB | SoFar3333 | * 只要有登入,系統首頁都會多出一個選項叫做「登出」,在登出以前都可以不限次數使用所有功能,若使用者選擇登出,則印出「(館員名字)已登出」並同時回到系統首頁。 ### 館藏登錄 * 在系統首頁輸入 1 之後,若尚未登入,則先印出「館員請先登入,才可以使用此功能!」,接著印出登入登出畫面,並依照登入登出的流程進行登入。 * 若已登入,讓使用者輸入 1、2 或 3 代表欲登錄的館藏是書籍、雜誌或是多媒體館藏,根據館藏類型的不同,接下來輸入不同的登錄所需資訊(如 下圖)。 * 輸入完成後,印出「館藏新增完成!」,並印出「是否繼續新增? Y/N」,若使用者輸入 Y,則重新再讓使用者輸入資訊新增館藏,若使用者輸入 N 則回到系統首頁。 ### 借書證註冊 * 在系統首頁輸入 2 之後,若尚未登入,則先印出「館員請先登入,才可以使用此功能!」,接著印出登入登出畫面,並依照登入登出的流程進行登入。 * 若已登入,根據下圖印出訊息讓使用者依序 輸入「姓名」與「出生年月日(YYYY/MM/DD)」,輸入完成後,給這位讀者借書證編號,編號規則是出生月分與日期加上系統累積的註冊人數。舉例來說,若輸入的出生年月日是 1998/09/22,且這位讀者是整個系統第一位申請借書證的人,則他的借書證編號是 09221,若輸入的出生年月日是 1997/04/06,且這位讀者是系統第二位申請借書證的人,則他的借書證編號是 04062,依此類推。 * 最後,印出「借書證申請完成!」並印出借書證編號,最後回到系統首頁。 ### 借閱 * 在系統首頁輸入 3 之後,若尚未登入,則先印出「館員請先登入,才可以使用此功能!」,接著印出登入登出畫面,並依照登入登出的流程進行登入。 * 若已登入,印出訊息請使用者輸入「借書證 編號」,輸入後,判定此借書證編號是否存在,若系統中查無此號,則印出「借書證編號輸入錯誤!重新輸入? Y/N」,若輸入 Y,則重新印出訊息輸入借書證編號,輸入 N 則回到系統首頁。 * 正確輸入借書證編號後,找出此借書證名下已借閱且尚未歸還的館藏數,若不含本次借閱,未歸還書籍數已達 5 本,則取消本次借閱,印出「已超出借閱本數限制!請歸還後再行借閱」後回到系統首頁。 * 接下來印出訊息請使用者輸入「分類號」,輸入後,判定此書是否存在,若系統查無此號,則 印出「分類號輸入錯誤!繼續借閱? Y/N」,若輸入 Y,則重新印出訊息輸入分類號,輸入 N 則回到系 統首頁。若該書籍已經被借出,則印出「此館藏已借出!繼續借閱? Y/N」,若輸入 Y,則重新印出訊 息輸入館藏分類號,輸入 N 則回到系統首頁。 * 借閱成功後,印出「借閱成功!您已借了 n 本書籍」,並在下一行印出借書證已借閱的所有館藏 標題(包含此次新增借閱的館藏),若有多本,則以逗號分隔。最後印出「繼續借閱? Y/N」,若輸入 Y,則重新判定使用者尚未歸還的館藏數,再一次進行借書流程,輸入 N 則回到系統首頁。 ### 歸還 * 在系統輸入 4 之後,若尚未登入,則先印出「館員請先登入,才可以使用此功能!」,接著印出登入登出畫面,並依照登入登出的流程進行登入。 * 若已登入,印出訊息輸入「館藏分類號」,輸入後,判定此書是否存在,若系統查無此號,則印出「分類號輸入錯誤!繼續歸還? Y/N」,若輸入 Y, 則重新印出訊息輸入書籍分類號,輸入 N 則回到系統首頁。 * 若書籍輸入正確,則先印出借書者姓名, 接著印出「(借書者姓名),(館藏名稱) 歸還成功!繼續歸還? Y/N」,若輸入 Y,則重新印出訊息輸入分類號,輸入 N 則回到系統首頁。 ### 查詢讀者狀態 * 系統輸入 5 之後,若尚未登入,則先印出「館員請先登入,才可以使用此功能!」,接著印出登入登出畫面,並依照登入登出的流程進行登入。 * 若已登入,印出訊息輸入「借閱證號」,輸入後,判定此讀者是否存在,若系統查無此號,則印出「查無此讀者!繼續歸還?Y/N」,若輸入 Y,則重新印出訊息輸入借閱證號,輸入 N 則回到系統首頁。 * 若借閱證號輸入正確,則先印出讀者姓名、出生年月日與已借閱且尚未歸還的館藏標題,若該讀者無未歸還的館藏,則印出「尚未借出任何館藏!」,若該讀者借出多個館藏,印出每個館藏標題時 以逗號隔開。 * 最後,同樣詢問「繼續查詢? Y/N」,若輸入 Y,則重新印出訊息輸入借閱證號,輸入 N 則回到系統首頁。 ### 查詢館藏狀態 * 系統輸入 6 之後,無論是否登入,都直接印出訊息「輸入 1 以館藏標題查詢\n 輸入 2 以作者查 詢\n 輸入 3 以識別號查詢」,若使用者輸入 1,則印出訊息請使用者輸入書名、輸入 2 則請使用者輸入作者、輸入 3 則輸入館藏識別碼進行尋找。 * 輸入館藏標題、作者姓名或識別號後,請比對系統中的館藏,若館藏標題、作者或識別號不存在,則印出「查無此館藏!繼續查詢 Y/N」,若輸入 Y,則重新 印出訊息讓使用者輸入 1/2/3,輸入 N 則回到系統首頁。 * 若是成功比對到館藏,根據館藏類型的不同,需印出不同的資訊: * 若是書籍,則印出該本書籍的 館藏標題、作者、出版社、識別號、分類號、館藏類型與館藏狀態 * 若是雜誌,則印出標題、作者、 出版社、期數、識別號、分類號、類型、狀態 * 若是多媒體,則印出標題、作者出版社、識別號、分 類號、館藏類型、格式、長度、狀態。 * 若查詢館藏時館藏狀態為已借出,且為館員已登入的狀態,則再輸出借出該書籍的借書證號碼。 ## 實作架構 ### Main.java #### 系統流程控制 ```java= import java.util.ArrayList; import java.util.Scanner; public class Main { /* * Librarians * private static Librarian Adam = new Librarian("Adam", "FarAwayLIB", "SoFar1111"); * private static Librarian Eva = new Librarian("Eva", "FarFarAwayLIB", "SoFar2222"); * private static Librarian Helen = new Librarian("Helen", "FarFarFarAwayLIB", "SoFar3333"); */ // Readers private static ArrayList<Reader> Readers = new ArrayList<Reader>(); // Menu private static Menu menu = new Menu(); // LogIn private static LogIn logIn = new LogIn(); private static boolean if_librarian_logIn = false; // Collections private static ArrayList<Collection> Collections = new ArrayList<Collection>(); // Scanner static Scanner sc = new Scanner(System.in); // 主程式 public static void main(String[] args) { String input; // 首頁 Homepage: do { // 印出首頁 if (if_librarian_logIn != true) menu.printMenu1(); else menu.printMenu2(); // 輸入功能編號 input = sc.nextLine(); if (input.equals("1") || input.equals("2") || input.equals("3") || input.equals("4") || input.equals("5")) { // 尚未登入 while (if_librarian_logIn != true) { if_librarian_logIn = logIn.librarian_logIn(); if (if_librarian_logIn) break; System.out.println("帳號密碼錯誤!是否重新輸入? Y/N"); String YorN = sc.nextLine(); if (YorN.equals("Y")) continue; else continue Homepage; } // 已登入 if (if_librarian_logIn) { // 館藏登錄 if (input.equals("1")) { addCollections(); continue Homepage; } // 借閱證註冊 else if (input.equals("2")) { register(); continue Homepage; } // 借閱 else if (input.equals("3")) { borrow(); continue Homepage; } // 歸還 else if (input.equals("4")) { returnCo(); continue Homepage; } // 查詢讀者狀態 else if (input.equals("5")) { searchRDinfo(); continue Homepage; } } break; } // 查詢館藏狀態 else if (input.equals("6")) { searchCOinfo(); continue; } // 登出 else if (input.equals("7")) { System.out.printf("%s已登出\n\n", logIn.logIn_user); if_librarian_logIn = false; logIn.logIn_user = ""; continue; } System.out.println("系統執行結束, 再見!"); } while (input.equals("exit") != true); sc.close(); } // 館藏登錄 static void addCollections() { System.out.println("***開始進行館藏登錄***"); String YorN = "Y"; while (YorN.equals("Y")) { System.out.println("館藏類型: 輸入 1 為書籍 / 輸入 2 為雜誌 / 輸入 3 為多媒體"); String type = sc.nextLine(); if (type.equals("1")) { System.out.print("題名:"); String title = sc.nextLine(); System.out.print("作者:"); String author = sc.nextLine(); System.out.print("出版社:"); String publisher = sc.nextLine(); System.out.print("識別號:"); String identifyNumber = sc.nextLine(); System.out.print("分類號:"); String classifyNumber = sc.nextLine(); Collections.add(new Book(title, author, publisher, identifyNumber, classifyNumber)); } else if (type.equals("2")) { System.out.print("題名:"); String title = sc.nextLine(); System.out.print("作者:"); String author = sc.nextLine(); System.out.print("出版社:"); String publisher = sc.nextLine(); System.out.print("年份:"); String year = sc.nextLine(); System.out.print("期數:"); String issue = sc.nextLine(); System.out.print("識別號:"); String identifyNumber = sc.nextLine(); System.out.print("分類號:"); String classifyNumber = sc.nextLine(); Collections.add(new Magazine(title, author, publisher, identifyNumber, classifyNumber, year, issue)); } else if (type.equals("3")) { System.out.print("題名:"); String title = sc.nextLine(); System.out.print("作者:"); String author = sc.nextLine(); System.out.print("出版社:"); String publisher = sc.nextLine(); System.out.print("多媒體類型:"); String mediaType = sc.nextLine(); System.out.print("長度(分鐘):"); String length = sc.nextLine(); System.out.print("識別號:"); String identifyNumber = sc.nextLine(); System.out.print("分類號:"); String classifyNumber = sc.nextLine(); Collections.add(new Multimedia(title, author, publisher, identifyNumber, classifyNumber, mediaType, length)); } System.out.println("館藏新增完成!"); System.out.println("是否繼續新增? Y/N"); YorN = sc.nextLine(); if (YorN.equals("N")) return; } } // 借閱證註冊 static void register() { System.out.println("***開始進行借閱證註冊***"); System.out.print("輸入申請人姓名: "); String name = sc.nextLine(); System.out.print("輸入申請人出生年月日(YYYY/MM/DD): "); String birthday = sc.nextLine(); Reader aReader = new Reader(name, birthday); Readers.add(aReader); System.out.println("借閱證申請完成!"); System.out.println("借閱證號碼為: " + aReader.getCardNumber()); } // 借閱 static void borrow() { System.out.println("***開始進行館藏借閱***"); boolean rdNotFound = true; while (rdNotFound) { System.out.print("輸入借書證編號: "); String cardNumber = sc.nextLine(); for (Reader rd: Readers) { if (rd.getCardNumber().equals(cardNumber)) { rdNotFound = false; // 若不含本次借閱,未歸還書籍數已達 5 本,則取消本次借閱 if (rd.borrowCnt >= 5) { System.out.println("已超出借閱本數限制!請歸還後再行借閱"); return; // go2Homepage } // 輸入分類號 String YorN = "Y"; while (YorN.equals("Y")) { boolean coNotFound = true; System.out.print("請輸入欲借閱館藏的分類號: "); String classifyNumber = sc.nextLine(); // 判定此館藏是否存在圖書館 for (Collection co: Collections) { if (co.classifyNumber.equals(classifyNumber)) { coNotFound = false; if (co.ifBorrowed) { System.out.println("此館藏已借出! 繼續借閱?"); YorN = sc.nextLine(); if (YorN.equals("Y")) break; else return; } rd.borrowCnt += 1; rd.borrowedCoList.add(co.title); co.ifBorrowed = true; co.borrower = rd.getName(); System.out.printf("借閱成功! %s (%s) 已借了 %d 本書籍\n", rd.getName(), rd.getCardNumber(), rd.borrowCnt); rd.printBorrowedCo(); // 印出借書證已借閱的所有館藏標題 System.out.println("繼續借閱? Y/N"); YorN = sc.nextLine(); if (YorN.equals("Y")) continue; else return; } } // 若系統查無此分類號 if (coNotFound) { System.out.println("分類號輸入錯誤! 繼續借閱? Y/N"); YorN = sc.nextLine(); if (YorN.equals("N")) return; else if (rd.borrowCnt >= 5) { System.out.println("已超出借閱本數限制!請歸還後再行借閱"); return; } } } return; } } // 若系統中查無此借書證編號 if (rdNotFound) { System.out.println("借書證編號輸入錯誤!重新輸入? Y/N"); String YorN = sc.nextLine(); if (YorN.equals("N")) return; } } } // 歸還 static void returnCo() { String YorN = "Y"; while (YorN.equals("Y")) { System.out.print("請輸入館藏分類號: "); String classifyNumber = sc.nextLine(); boolean numNotFound = true; for (Collection co: Collections) { if (co.classifyNumber.equals(classifyNumber)) { numNotFound = false; System.out.printf("%s, %s 歸還成功! 繼續歸還? Y/N", co.borrower, co.title); for (Reader rd: Readers) { if (rd.getName().equals(co.borrower)) { rd.borrowCnt -= 1; rd.borrowedCoList.remove(co.title); } } co.borrower = ""; co.ifBorrowed = false; YorN = sc.nextLine(); if (YorN.equals("N")) return; else break; } } if (numNotFound) { System.out.println("分類號輸入錯誤!"); System.out.println("繼續歸還? Y/N"); YorN = sc.nextLine(); if (YorN.equals("N")) return; } } } // 查詢讀者狀態 static void searchRDinfo() { String YorN = "Y"; while (YorN.equals("Y")) { boolean cdNotFound = true; System.out.print("請輸入借閱證號: "); String cardNumber = sc.nextLine(); for (Reader rd: Readers) { if (rd.getCardNumber().equals(cardNumber)) { cdNotFound = false; rd.printInfo(); System.out.println("繼續查詢?"); YorN = sc.nextLine(); if (YorN.equals("N")) return; else break; } } if (cdNotFound) { System.out.println("查無此讀者! 繼續查詢? Y/N"); YorN = sc.nextLine(); if (YorN.equals("N")) return; } } } // 查詢館藏狀態 static void searchCOinfo() { String YorN = "Y"; while (YorN.equals("Y")) { System.out.println("***開始進行館藏查詢***"); System.out.println("輸入 1 以館藏標題查詢\n輸入 2 以作者查詢\n輸入 3 以識別號查詢"); String mode; mode = sc.nextLine(); if (mode.equals("1")) { System.out.print("請輸入館藏標題:"); String title = sc.nextLine(); for (Collection co: Collections) { if (co.title.equals(title)) { co.listCollectionInformation(); break; } } } else if (mode.equals("2")) { System.out.print("請輸入作者姓名:"); String author = sc.nextLine(); for (Collection co: Collections) { if (co.author.equals(author)) { co.listCollectionInformation(); break; } } } else if (mode.equals("3")) { System.out.print("請輸入館藏識別號:"); String identifyNumber = sc.nextLine(); for (Collection co: Collections) { if (co.identifyNumber.equals(identifyNumber)) { co.listCollectionInformation(); break; } } } System.out.println("繼續查詢? Y/N"); YorN = sc.nextLine(); if (YorN.equals("N")) return; } } } ``` ### Collection.java #### 館藏 ```java= public abstract class Collection { // Variables String title; String author; String publisher; String identifyNumber; String classifyNumber; String borrower; boolean ifBorrowed; // Constructor Collection (String title, String author, String publisher, String identifyNumber, String classifyNumber) { this.title = title; this.author = author; this.publisher = publisher; this.identifyNumber = identifyNumber; this.classifyNumber = classifyNumber; this.ifBorrowed = false; } // Method public abstract void listCollectionInformation(); } class Book extends Collection { // Constructor Book (String title, String author, String publisher, String identifyNumber, String classifyNumber) { super(title, author, publisher, identifyNumber, classifyNumber); } // Method public void listCollectionInformation() { System.out.println("================================================"); System.out.printf("題名 / %s\n", title); System.out.printf("作者 / %s\n", author); System.out.printf("出版社 / %s\n", publisher); System.out.printf("識別號 / %s\n", identifyNumber); System.out.printf("分類號 / %s\n", classifyNumber); System.out.println("館藏類型 / 書籍"); if (this.ifBorrowed) System.out.println("館藏狀態 / 已借出"); else System.out.println("館藏狀態 / 架上"); System.out.println("================================================"); } } class Magazine extends Collection { // Variables private String year; private String issue; // Constructor Magazine (String title, String author, String publisher, String identifyNumber, String classifyNumber, String year, String issue) { super(title, author, publisher, identifyNumber, classifyNumber); this.year = year; this.issue = issue; } // Method public void listCollectionInformation() { System.out.println("================================================"); System.out.printf("題名 / %s\n", title); System.out.printf("作者 / %s\n", author); System.out.printf("出版社 / %s\n", publisher); System.out.printf("期數 / %s 年第 %s 期\n", year, issue); System.out.printf("識別號 / %s\n", identifyNumber); System.out.printf("分類號 / %s\n", classifyNumber); System.out.println("館藏類型 / 雜誌"); if (this.ifBorrowed) System.out.println("館藏狀態 / 已借出"); else System.out.println("館藏狀態 / 架上"); System.out.println("================================================"); } } class Multimedia extends Collection { // Variables private String mediaType; private String length; // Constructor Multimedia (String title, String author, String publisher, String identifyNumber, String classifyNumber, String mediaType, String length) { super(title, author, publisher, identifyNumber, classifyNumber); this.mediaType = mediaType; this.length = length; } // Method public void listCollectionInformation() { System.out.println("================================================"); System.out.printf("標題 / %s\n", title); System.out.printf("作者 / %s\n", author); System.out.printf("出版社 / %s\n", publisher); System.out.printf("識別號 / %s\n", identifyNumber); System.out.printf("分類號 / %s\n", classifyNumber); System.out.println("館藏類型 / 多媒體影音"); System.out.printf("格式 / %s\n", mediaType); System.out.printf("長度(分鐘) / %s\n", length); if (this.ifBorrowed) System.out.println("館藏狀態 / 已借出"); else System.out.println("館藏狀態 / 架上"); System.out.println("================================================"); } } ``` ### Human.java #### 圖書館員、讀者 ```java= import java.util.ArrayList; class Librarian { // Variables String name; String account; String password; // Constructor Librarian () {}; Librarian (String name, String account, String password) { this.name = name; this.account = account; this.password = password; } } class Reader { // Variables private String name; private String birthday; private String cardNumber; public int borrowCnt; public ArrayList<String> borrowedCoList; private static int readerCnt = 0; // Constructor Reader (String name, String birthday) { readerCnt++; this.name = name; this.birthday = birthday; this.borrowedCoList = new ArrayList<String>(); // 編號 = 出生月分 + 日期 + 系統累積的註冊人數 String temp[] = birthday.split("/"); this.cardNumber = temp[1] + temp[2] + readerCnt; this.borrowCnt = 0; } // Method public String getName() { return name; } public String getCardNumber() { return cardNumber; } public void printBorrowedCo() { System.out.print("已借閱館藏: "); for (int i = 0; i < borrowCnt - 1; i++) { System.out.print(borrowedCoList.get(i) + ","); } System.out.println(borrowedCoList.get(borrowCnt - 1)); } public void printInfo() { System.out.println("姓名 / " + name); System.out.println("出生年月日 / " + birthday); if (borrowCnt == 0) System.out.println("已借閱館藏 / 尚未借出任何館藏!"); else { this.printBorrowedCo(); } } } ``` ### LogIn.java #### 實作登入功能 ```java= import java.util.Scanner; public class LogIn { // Variables boolean logIn; String logIn_user; // Constructor LogIn() { logIn = false; logIn_user = ""; } // Method boolean librarian_logIn() { Scanner sc = new Scanner(System.in); System.out.println("館員請先登入,才可以使用此功能!"); System.out.print("請輸入帳號: "); String account = sc.nextLine(); System.out.print("請輸入密碼: "); String password = sc.nextLine(); // sc.close(); 主程式再關 if (account.equals("FarAwayLIB") && password.equals("SoFar1111")) { System.out.println("嗨 Adam, 歡迎登入!\n"); logIn_user = "Adam"; return true; } else if (account.equals("FarFarAwayLIB") && password.equals("SoFar2222")) { System.out.println("嗨 Eva, 歡迎登入!\n"); logIn_user = "Eva"; return true; } else if (account.equals("FarFarFarAwayLIB") && password.equals("SoFar3333")) { System.out.println("嗨 Helen, 歡迎登入!\n"); logIn_user = "Helen"; return true; } else { return false; } } } ``` ### Menu.java #### 登入登出畫面 ```java= public class Menu { public void printMenu1() { System.out.println("================================================"); System.out.println("歡迎使用圖書資訊系統"); System.out.println("輸入 1 進行館藏登錄"); System.out.println("輸入 2 進行借閱證註冊"); System.out.println("輸入 3 進行館藏借閱"); System.out.println("輸入 4 進行館藏歸還"); System.out.println("輸入 5 查詢讀者狀態"); System.out.println("輸入 6 查詢館藏狀態"); System.out.println("輸入 exit 以離開"); System.out.println("================================================"); } public void printMenu2() { System.out.println("================================================"); System.out.println("歡迎使用圖書資訊系統"); System.out.println("輸入 1 進行館藏登錄"); System.out.println("輸入 2 進行借閱證註冊"); System.out.println("輸入 3 進行館藏借閱"); System.out.println("輸入 4 進行館藏歸還"); System.out.println("輸入 5 查詢讀者狀態"); System.out.println("輸入 6 查詢館藏狀態"); System.out.println("輸入 7 以登出"); System.out.println("輸入 exit 以離開"); System.out.println("================================================"); } } ```