فهرست منبع

feat: 版本1

SongZihuan 1 سال پیش
کامیت
58a94fd995

+ 38 - 0
.gitignore

@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 20 - 0
README.md

@@ -0,0 +1,20 @@
+# 图书馆管理工具 (Demo)
+## 介绍
+这是一个模拟图书馆管理工具的Demo。使用简单,基于内存存储。
+
+## 构建
+安装Maven,然后构建
+
+```shell
+maven package dependency:copy-dependencies -DoutputDirectory=target/lib
+```
+
+## 生成目录
+生成target目录,可执行的jar为`library_manager.jar`,依赖库为`lib`。
+执行方式
+```shell
+java -jar ./target/library_manager.jar
+```
+
+## 打包
+可以使用jlink和jpackage打包。

+ 41 - 0
pom.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.sogzh</groupId>
+    <artifactId>librarymanager</artifactId>
+    <version>1.0</version>
+
+    <properties>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+    </dependencies>
+
+    <build>
+        <finalName>library_manager</finalName>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>3.3.0</version>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <addClasspath>true</addClasspath>
+                            <classpathPrefix>lib/</classpathPrefix>
+                            <mainClass>com.songzh.librarymanager.controller.Controller</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 241 - 0
src/main/java/com/songzh/librarymanager/controller/Controller.java

@@ -0,0 +1,241 @@
+package com.songzh.librarymanager.controller;
+
+import com.songzh.librarymanager.error.*;
+import com.songzh.librarymanager.model.*;
+import com.songzh.librarymanager.viewer.Viewer;
+
+public class Controller {
+    private final Viewer viewer;
+
+    private final Library libary;
+    private Book book;
+    private Author author;
+
+    private Status status;
+
+    static Controller createWithInit() {
+        var ctrl = new Controller();
+        ctrl.init();
+        return ctrl;
+    }
+
+    public Controller() {
+        this.libary = new Library();
+        this.viewer = new Viewer();
+        this.status = Status.Library;
+    }
+
+    private void init() {
+        var author = new Author("佳程");
+        var book1 = new SCIBook(author, "如何成为顶级前端?", "20040101-xxx222yyz");
+        var book2 = new ScoreBook(author, "前端保姆教程", 98);
+        author.addBook(book1);
+        author.addBook(book2);
+
+        this.libary.addAuthor(author);
+    }
+
+    private void mainloop() {
+        for (;;) {
+            try {
+                this.viewer.showInfo(this.header());
+                this.viewer.showInfo(this.menu());
+                this.viewer.showInfo(this.footer());
+
+                var opt = this.viewer.getMenuInput();
+
+                switch (this.status) {
+                    case Library -> {
+                        LIBARYOPT:
+                        switch (opt) {
+                            case 1 -> {
+                                try {
+                                    this.book = this.libary.getBook(this.viewer.getBookName());
+                                    this.status = Status.Book;
+                                } catch (BookNotFound bookNotFound) {
+                                    this.viewer.showInfo(String.format("书本未找到:%s", bookNotFound.bookName()));
+                                }
+                            }
+                            case 2 -> {
+                                try {
+                                    this.author = this.libary.getAuthor(this.viewer.getAuthorName());
+                                    this.status = Status.Author;
+                                } catch (AuthorNotFound authorNotFound) {
+                                    this.viewer.showInfo(String.format("作者未找到:%s", authorNotFound.authorName()));
+                                }
+                            }
+                            case 3 -> {
+                                Author author;
+                                try {
+                                    author = this.libary.getAuthor(this.viewer.getAuthorName());
+                                } catch (AuthorNotFound authorNotFound) {
+                                    this.viewer.showInfo(String.format("作者未找到:%s", authorNotFound.authorName()));
+                                    break LIBARYOPT;
+                                }
+
+                                var bookName = this.viewer.getBookName();
+                                var bookType = this.viewer.getBookType();
+                                Book book;
+
+                                switch (bookType) {
+                                    case "SCI" -> {
+                                        var sciNumber = this.viewer.getSCINumber();
+                                        book = new SCIBook(author, bookName, sciNumber);
+                                    }
+                                    case "SCORE" -> {
+                                        int score;
+                                        try {
+                                            score = this.viewer.getScore();
+                                        } catch (NumberFormatException e) {
+                                            this.viewer.showInfo(String.format("评分分数解析错误:%s", e.getMessage()));
+                                            break LIBARYOPT;
+                                        }
+
+                                        book = new ScoreBook(author, bookName, score);
+                                    }
+                                    default -> {
+                                        this.viewer.showInfo(String.format("书本类型不支持:%s", bookType));
+                                        break LIBARYOPT;
+                                    }
+                                }
+
+                                libary.addBook(book);
+                            }
+                            case 5 -> {
+                                var author = this.libary.authors();
+                                author.forEach((b)->{
+                                    this.viewer.showInfo(String.format("* %s", b));
+                                });
+                            }
+                            case 6 -> {
+                                var books = this.libary.books();
+                                books.forEach((b)->{
+                                    this.viewer.showInfo(String.format("* %s", b));
+                                });
+                            }
+                            default -> {
+                                this.viewer.showInfo(String.format("不支持的操作:%d", opt));
+                            }
+                        }
+                    }
+                    case Author -> {
+                        AUTHOROPT:
+                        switch (opt) {
+                            case 1 -> {
+                                this.viewer.showInfo(this.author.name());
+                                var books = this.author.books();
+                                books.forEach((b)->{
+                                    this.viewer.showInfo(String.format("* %s", b));
+                                });
+                            }
+                            case 2 -> {
+                                try {
+                                    this.book = this.author.getBook(this.viewer.getBookName());
+                                    this.status = Status.Book;
+                                } catch (BookNotFound bookNotFound) {
+                                    this.viewer.showInfo(String.format("书本未找到:%s", bookNotFound.bookName()));
+                                }
+                            }
+                            case 3 -> {
+                                var bookName = this.viewer.getBookName();
+                                var bookType = this.viewer.getBookType();
+                                Book book;
+
+                                switch (bookType) {
+                                    case "SCI" -> {
+                                        var sciNumber = this.viewer.getSCINumber();
+                                        book = new SCIBook(this.author, bookName, sciNumber);
+                                    }
+                                    case "SCORE" -> {
+                                        int score;
+                                        try {
+                                            score = this.viewer.getScore();
+                                        } catch (NumberFormatException e) {
+                                            this.viewer.showInfo(String.format("评分分数解析错误:%s", e.getMessage()));
+                                            break AUTHOROPT;
+                                        }
+
+                                        book = new ScoreBook(this.author, bookName, score);
+                                    }
+                                    default -> {
+                                        this.viewer.showInfo(String.format("书本类型不支持:%s", bookType));
+                                        break AUTHOROPT;
+                                    }
+                                }
+
+                                this.author.addBook(book);
+                            }
+                            default -> {
+                                this.viewer.showInfo(String.format("不支持的操作:%d", opt));
+                            }
+                        }
+                    }
+                    case Book -> {
+                        BOOKOPT:
+                        switch (opt) {
+                            case 1 -> {
+                                this.viewer.showInfo(this.book.identity());
+                            }
+                            case 2 -> {
+                                this.author = this.book.author();
+                                this.status = Status.Author;
+                            }
+                            default -> {
+                                this.viewer.showInfo(String.format("不支持的操作:%d", opt));
+                            }
+                        }
+                    }
+                }
+
+
+            } catch (Exit ignored) {
+                return;
+            } catch (Cancel ignored) {
+                this.viewer.showInfo("已取消执行");
+            } catch (Back ignored) {
+                this.status = Status.Library;
+            }
+        }
+    }
+
+    private String menu() {
+        return switch (this.status) {
+            case Library -> """
+                    1) 查找图书
+                    2) 查找作者
+                    3) 新增图书
+                    4) 新增作者
+                    5) 查看图书馆作者列表
+                    6) 查看图书馆图书列表""";
+            case Book -> """
+                    1) 查看图书信息
+                    2) 查找作者""";
+            case Author -> """
+                    1) 查看作者信息
+                    2) 查找图书
+                    3) 新增图书""";
+        };
+    }
+
+    private String header() {
+        return switch (this.status) {
+            case Library -> "图书馆模式";
+            case Book -> String.format("图书:%s", this.book.identity());
+            case Author -> String.format("作者:%s", this.book.identity());
+        };
+    }
+
+    private String footer() {
+        return """
+                输入 "q" 退出,输入 "n" 返回图书馆模式。""";
+    }
+
+    public static void main(String[] args) {
+        System.out.println("""
+                欢迎使用 顶级前端 Java!!! 的图书馆管理系统。
+                本系统基于内存管理图书,不做任何持久化处理。
+                谢谢!
+                """);
+        Controller.createWithInit().mainloop();
+    }
+}

+ 5 - 0
src/main/java/com/songzh/librarymanager/controller/Status.java

@@ -0,0 +1,5 @@
+package com.songzh.librarymanager.controller;
+
+public enum Status {
+    Library, Book, Author
+}

+ 13 - 0
src/main/java/com/songzh/librarymanager/error/AuthorNotFound.java

@@ -0,0 +1,13 @@
+package com.songzh.librarymanager.error;
+
+public class AuthorNotFound extends Exception {
+    private final String authorName;
+    public AuthorNotFound(String authorName) {
+        super("作者未找到");
+        this.authorName = authorName;
+    }
+
+    public String authorName() {
+        return this.authorName;
+    }
+}

+ 5 - 0
src/main/java/com/songzh/librarymanager/error/Back.java

@@ -0,0 +1,5 @@
+package com.songzh.librarymanager.error;
+
+public class Back extends Exception {
+    public Back() {}
+}

+ 13 - 0
src/main/java/com/songzh/librarymanager/error/BookNotFound.java

@@ -0,0 +1,13 @@
+package com.songzh.librarymanager.error;
+
+public class BookNotFound extends Exception {
+    private final String bookName;
+    public BookNotFound(String bookName) {
+        super("书本未找到");
+        this.bookName = bookName;
+    }
+
+    public String bookName() {
+        return this.bookName;
+    }
+}

+ 5 - 0
src/main/java/com/songzh/librarymanager/error/Cancel.java

@@ -0,0 +1,5 @@
+package com.songzh.librarymanager.error;
+
+public class Cancel extends Exception {
+    public Cancel() {}
+}

+ 5 - 0
src/main/java/com/songzh/librarymanager/error/Exit.java

@@ -0,0 +1,5 @@
+package com.songzh.librarymanager.error;
+
+public class Exit extends Exception {
+    public Exit() {}
+}

+ 37 - 0
src/main/java/com/songzh/librarymanager/model/Author.java

@@ -0,0 +1,37 @@
+package com.songzh.librarymanager.model;
+
+import java.util.Set;
+import java.util.TreeMap;
+
+import com.songzh.librarymanager.error.*;
+
+public class Author {
+    private final String name;
+
+    private final TreeMap<String, Book> books;
+
+    public Author(String name) {
+        this.name = name;
+        this.books = new TreeMap<>();
+    }
+
+    public String name() {
+        return this.name;
+    }
+
+    public void addBook(Book book) {
+        this.books.put(book.name(), book);
+    }
+
+    public Book getBook(String name) throws BookNotFound {
+        var book = this.books.get(name);
+        if (book == null) {
+            throw new BookNotFound(name);
+        }
+        return book;
+    }
+
+    public Set<String> books() {
+        return this.books.keySet();
+    }
+}

+ 27 - 0
src/main/java/com/songzh/librarymanager/model/Book.java

@@ -0,0 +1,27 @@
+package com.songzh.librarymanager.model;
+
+public class Book {
+    private final String name;
+    private final Author author;
+
+    Book(Author author, String name) {
+        this.author = author;
+        this.name = name;
+    }
+
+    public String name() {
+        return this.name;
+    }
+
+    public Author author() {
+        return this.author;
+    }
+
+    public String identity() {
+        return this.name;
+    }
+
+    public String toString() {
+        return String.format("<书本 %s (作者: %s)>", this.identity(), this.author().name());
+    }
+}

+ 62 - 0
src/main/java/com/songzh/librarymanager/model/Library.java

@@ -0,0 +1,62 @@
+package com.songzh.librarymanager.model;
+
+import com.songzh.librarymanager.error.AuthorNotFound;
+import com.songzh.librarymanager.error.BookNotFound;
+
+import java.util.Set;
+import java.util.TreeMap;
+
+public class Library {
+    private final TreeMap<String, Book> books;
+    private final TreeMap<String, Author> authors;
+
+    public Library() {
+        this.books = new TreeMap<>();
+        this.authors = new TreeMap<>();
+    }
+
+    public Book getBook(String name) throws BookNotFound {
+        var book = this.books.get(name);
+        if (book == null) {
+            throw new BookNotFound(name);
+        }
+        return book;
+    }
+
+    public Author getAuthor(String name) throws AuthorNotFound {
+        var author = this.authors.get(name);
+        if (author == null) {
+            throw new AuthorNotFound(name);
+        }
+        return author;
+    }
+
+    public void addBook(Book book) {
+        this.books.put(book.name(), book);
+
+        var author = book.author();
+        this.authors.put(author.name(), author);
+    }
+
+    public void addAuthor(Author author) {
+        this.authors.put(author.name(), author);
+
+        var books = author.books();
+        books.forEach((String name)->{
+            try {
+                var book = author.getBook(name);
+                this.books.put(book.name(), book);
+            } catch (BookNotFound ignored) {
+                // 跳过
+            }
+        });
+    }
+
+    public Set<String> books() {
+        return this.books.keySet();
+    }
+
+    public Set<String> authors() {
+        return this.authors.keySet();
+    }
+}

+ 19 - 0
src/main/java/com/songzh/librarymanager/model/SCIBook.java

@@ -0,0 +1,19 @@
+package com.songzh.librarymanager.model;
+
+public class SCIBook extends Book {
+    private final String sciNumber;
+
+    public SCIBook(Author author, String name, String sciNumber) {
+        super(author, name);
+        this.sciNumber = sciNumber;
+    }
+
+    @Override
+    public String identity() {
+        return String.format("%s:%s", super.identity(), this.sciNumber);
+    }
+
+    public String sciNumber() {
+        return this.sciNumber;
+    }
+}

+ 19 - 0
src/main/java/com/songzh/librarymanager/model/ScoreBook.java

@@ -0,0 +1,19 @@
+package com.songzh.librarymanager.model;
+
+public class ScoreBook extends Book {
+    private final int score;
+
+    public ScoreBook(Author author, String name, int score) {
+        super(author, name);
+        this.score = score;
+    }
+
+    @Override
+    public String identity() {
+        return String.format("%s <score %d>", super.identity(), this.score);
+    }
+
+    public int score() {
+        return this.score;
+    }
+}

+ 79 - 0
src/main/java/com/songzh/librarymanager/viewer/Viewer.java

@@ -0,0 +1,79 @@
+package com.songzh.librarymanager.viewer;
+
+import com.songzh.librarymanager.error.Back;
+import com.songzh.librarymanager.error.Cancel;
+import com.songzh.librarymanager.error.Exit;
+import com.songzh.librarymanager.model.Library;
+
+import java.util.InputMismatchException;
+import java.util.Objects;
+import java.util.Scanner;
+
+public class Viewer {
+    private final Scanner scanner;
+
+    public Viewer() {
+        this.scanner = new Scanner(System.in);
+    }
+
+    public void showInfo(String data) {
+        System.out.println(data);
+    }
+
+    public int getMenuInput() throws Exit {
+        try {
+            System.out.print("你的操作 >>> ");
+            var opt = this.scanner.nextInt();
+
+            if (this.scanner.hasNextLine()) {
+                this.scanner.nextLine();
+            }
+
+            return opt;
+        } catch (InputMismatchException e) {
+            var n = this.scanner.next();
+            if (n.equals("q")) {
+                throw new Exit();
+            }
+            return -1;
+        }
+    }
+
+    private String getInput() throws Cancel, Exit, Back {
+        var res = this.scanner.nextLine();
+        if (res.isEmpty()) {
+            throw new Cancel();
+        } else if (res.equals("n")) {
+            throw new Back();
+        } else if (res.equals("q")) {
+            throw new Exit();
+        }
+        return res;
+    }
+
+    public String getBookName() throws Cancel, Exit, Back {
+        System.out.print("输入书名:");
+        return this.getInput();
+    }
+
+    public String getAuthorName() throws Cancel, Exit, Back {
+        System.out.print("输入作者名称:");
+        return this.getInput();
+    }
+
+    public String getBookType() throws Cancel, Exit, Back {
+        System.out.print("输入书本类型名称 [SCI:学术书,SCORE:评分书]:");
+        return this.getInput();
+    }
+
+    public String getSCINumber() throws Cancel, Exit, Back {
+        System.out.print("输入书本SCI代码:");
+        return this.getInput();
+    }
+
+    public int getScore() throws Cancel, Exit, NumberFormatException, Back {
+        System.out.print("输入书本评分分数:");
+        var scoreString = this.getInput();
+        return Integer.parseInt(scoreString);
+    }
+}

+ 2 - 0
src/main/java/module-info.java

@@ -0,0 +1,2 @@
+module com.songzh.librarymanager {
+}