The author has something to say:
About this blog, it mainly records an assignment in class. The assignment requirements are as follows (I. assignment book of library management system). The project is mainly to practice some knowledge of JavaSE (mainly related to encapsulating and inheriting polymorphic sets). It does not interact with the data back-end or use any framework.
1, Book management system assignment:
Description:
Library management system will have different complexity because of the number, type and operation of books. The maintenance of basic information, book borrowing, return and query are usually the basic functions of the library management system. In large-scale and more business libraries, more complex functions such as book inventory management and sales management are also needed.
Relevant data tables:
Function realization requirements:
- Implement the interface IAction, which includes five methods: add (insert), del (delete), getCount (data size), getlistInfo (list output) and find (find). The method of realizing IAction interface for book information class, reader information class, borrowing information class and user information class requires the use of set framework technology. In the test class, various methods such as insertion, deletion, size, list output and query are tested.
2. Realize the user interaction function of the library management system, including the display of the user menu and the addition, deletion, query, list and other functions of the data after the user selects the menu (respectively realize the operation of book information, reader information, borrowing information and user information). The specific function menu is as follows:
0: system exit
1: Book information list display
2: New book information
3: Book information deletion
4: Book information search (search by book title)
6: Reader information list display
7: New reader information
8: Reader information deletion
9: Reader information search (search by name)
10: Borrowing information list display
11: New borrowing information
12: Delete borrowing information
13: Borrowing information search (search by book title)
14: User information list display
15: User information addition
16: User information deletion
17: User information search (search by user name)
2, Project structure
1. Project framework
2.SystemData.java:
Since there is no data interaction with the database, the data of the system is shared through static attributes:
Related learning links:
java basics review - static keyword
3.LibraySystem.java
LibraySystem.java is the overall framework of the library management:
Start the library management system through start():
Since the functions of several functional modules are only CRUD operation, a composite method is used, and the parameter is IAction interface (polymorphic exercise):
Full code:
package com.zhumin.controller; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import com.zhumin.librarysystem.ben.Book; import com.zhumin.librarysystem.ben.Borrow; import com.zhumin.librarysystem.ben.Reader; import com.zhumin.librarysystem.ben.User; import com.zhumin.service.IAction; /** * @ClassName LibraySystem * @Description Book system class * @author Doodle programmer shovel shit Officer * @date 2021 October 26 * */ public class LibraySystem { public static Map<Integer, String>MANAGERVIEW_MENU,LIBRAYSYSTE_MMENU; //Initialize system data static{ SystemData.BORROWLIST_SYSTEM=new ArrayList<>(); SystemData.TEST_USER=new User("10001", "admin", "123456", true); //Book information ArrayList<Book>aBooks=new ArrayList<>(); aBooks.add(new Book("AA001001", "Java Basic introduction", "computer", "Zhang San", "nothing", "tsinghua university press ", new Date(), 44.5,50)); aBooks.add(new Book("AA001002", "Java Programming thought", "computer", "Li Si", "nothing", "Machinery Industry Press", new Date(), 108,100)); aBooks.add(new Book("AA001003", "data structure", "computer", "Wang Wu", "nothing", "Electronic Industry Press", new Date(), 88,50)); SystemData.BOOKLIST_SYSTEM=aBooks; //User information ArrayList<User>aUsers=new ArrayList<>(); aUsers.add(SystemData.TEST_USER); aUsers.add(new User("1001", "Zhang San", "123456", false)); aUsers.add(new User("1002", "Li Si", "123456", false)); aUsers.add(new User("1003", "Wang Mazi", "123456", false)); aUsers.add(new User("1004", "Wang Baoqiang", "123456", false)); aUsers.add(new User("1005", "Lu Benwei", "123456", false)); SystemData.USERLIST_SYSTEM=aUsers; //Reader information ArrayList<Reader>aReaders=new ArrayList<>(); aReaders.add(new Reader("1001", "Zhang San", "Ordinary readers", "male", 5, 30)); aReaders.add(new Reader("1002", "Li Si", "Ordinary readers", "male", 5, 30)); aReaders.add(new Reader("1003", "Wang Mazi", "Ordinary readers", "male", 5, 30)); aReaders.add(new Reader("1004", "Wang Baoqiang", "Ordinary readers", "male", 5, 30)); aReaders.add(new Reader("1005", "Lu Benwei", "Ordinary readers", "male", 5, 30)); SystemData.READERLIST_SYSTEM=aReaders; //Borrowing information ArrayList<Borrow>aBorrows=new ArrayList<>(); aBorrows.add(new Borrow("AA001001", "123456789", "1001", "2021-10-27", "Not yet", false)); aBorrows.add(new Borrow("AA001001", "985522212", "1002", "2021-10-27", "Not yet", false)); aBorrows.add(new Borrow("AA001001", "464682223", "1002", "2021-10-27", "Not yet", false)); aBorrows.add(new Borrow("AA001001", "135656132", "1003", "2021-10-27", "Not yet", false)); //Menu information initialization MANAGERVIEW_MENU=new HashMap<Integer, String>(); MANAGERVIEW_MENU.put(1, "1:List display"); MANAGERVIEW_MENU.put(2, "2:New information"); MANAGERVIEW_MENU.put(3, "3:Information deletion"); MANAGERVIEW_MENU.put(4, "4:Information search"); MANAGERVIEW_MENU.put(5, "5:Return to the previous level"); LIBRAYSYSTE_MMENU=new HashMap<>(); LIBRAYSYSTE_MMENU.put(0, "You have entered the exit module~"); LIBRAYSYSTE_MMENU.put(1, "Welcome to the library management module~"); LIBRAYSYSTE_MMENU.put(2, "Welcome to the borrowing management module~"); LIBRAYSYSTE_MMENU.put(3, "Welcome to the reader management module~"); LIBRAYSYSTE_MMENU.put(4, "Welcome to the user management module~"); } public void start() { //Program running System.out.println("----------------Book system----------------"); System.out.println("Welcome to the book system!"); if (!SystemData.STATUS_USER) { //User login login(); } System.out.println("welcome"+SystemData.CURRENT_USER.getUsername()+"Enter the library management system~"); while(SystemData.STATUS_USER){ System.out.println("Book system function panel:"); System.out.println("0:System exit,1:Library management page,2:Borrowing management page,3:Reader information page,4:User information page"); System.out.println("Enter your options:"); int num=new Scanner(System.in).nextInt(); //Prompt the user to enter which module if (num>=0&&num<=LIBRAYSYSTE_MMENU.size()) { System.out.println(LIBRAYSYSTE_MMENU.get(num)); } switch (num) { case 0: exit(); break; case 1: operateReuse(new Book(),MANAGERVIEW_MENU); break; case 2: operateReuse(new Borrow(),MANAGERVIEW_MENU); break; case 3: operateReuse(new Reader(),MANAGERVIEW_MENU); break; case 4: operateReuse(new User(),MANAGERVIEW_MENU); default: System.out.println("invalid input,Please re-enter!"); break; } } } private void login() { //Set login to true to run SystemData.STATUS_USER=true; if (SystemData.CURRENT_USER==null) { while(true){ System.out.println("No user is currently logged in!"); System.out.println("1:Login user,2:Registered user"); System.out.println("Enter your option number:"); int num=new Scanner(System.in).nextInt(); if (num==2) { new User().add(); break; }else if (num==1) { String userName,passWord; System.out.println("Enter account number:"); userName=new Scanner(System.in).nextLine(); System.out.println("Input password:"); passWord=new Scanner(System.in).nextLine(); //Instantiate User object User user=new User(); user.setUsername(userName); user.setPassword(passWord); //Log in if (user.userLogin(user)) { System.out.println("Login successful!"); break; }else { System.out.println("Login failed!"); } }else { System.out.println("Invalid input, please re-enter!"); } } } } //Exit the system private void exit() { // TODO Auto-generated method stub SystemData.STATUS_USER=false; System.out.println("looking forward to your next visit!"); System.out.println("Has exited the system!"); return; } //Function option reuse method private void operateReuse(IAction iAction,Map<Integer, String> menu) { // TODO Auto-generated method stub while (true) { showMenu(menu); switch (new Scanner(System.in).nextInt()) { case 1: iAction.getlistInfo(); break; case 2: iAction.add(); break; case 3: iAction.del(); break; case 4: iAction.find(); break; case 5: return; default: System.out.println("invalid input,Please re-enter!"); break; } } } //Display menu reuse method private void showMenu(Map<Integer, String> menu) { System.out.println("menu:"); // TODO Auto-generated method stub for (Map.Entry<Integer, String> entry :menu.entrySet()) { System.out.println(entry.getValue()); } System.out.println("Enter your options:"); } }
4.Book,Borrow,Reader,User
Book, mirror, reader and user implement IAction interface, and the method of implementing the interface:
(the CRUD operation here is actually the operation of the set, which is used to practice the set knowledge.)
Book.java:
package com.zhumin.librarysystem.ben; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Scanner; import com.zhumin.controller.SystemData; import com.zhumin.service.IAction; /** * @ClassName Book * @Description Book entity class * @author Doodle programmer shovel shit Officer * @date 2021 October 26 * */ public class Book implements IAction{ private String id="AA0000001"; private String bookname; private String booktype="science and technology"; private String author; private String translator; private String publisher; private Date publish_time; private double price=28; private int stock=1; //Construction method public Book(String id, String bookname, String booktype, String author, String translator, String publisher, Date publish_time, double price, int stock) { this.id = id; this.bookname = bookname; this.booktype = booktype; this.author = author; this.translator = translator; this.publisher = publisher; this.publish_time = publish_time; this.price = price; this.stock = stock; } public Book() { } //get and set accessors for properties public String getId() { return id; } public void setId(String id) { this.id = id; } public String getBookname() { return bookname; } public void setBookname(String bookname) { this.bookname = bookname; } public String getBooktype() { return booktype; } public void setBooktype(String booktype) { this.booktype = booktype; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getTranslator() { return translator; } public void setTranslator(String translator) { this.translator = translator; } public String getPublisher() { return publisher; } public void setPublisher(String publisher) { this.publisher = publisher; } public Date getPublish_time() { return publish_time; } public void setPublish_time(Date publish_time) { this.publish_time = publish_time; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getStock() { return stock; } public void setStock(int stock) { this.stock = stock; } @Override public String toString() { return "Book number:" + id + ", Book name:" + bookname + ", Book type:" + booktype + ", author:" + author + ", translate:" + translator + ", press:" + publisher + ", Publication time:" + new SimpleDateFormat("yyyy year MM month dd day hh Time mm branch ss second").format(publish_time) + ", Price:" + price + ", stock:" + stock + "]"; } @Override public boolean add() { Scanner scanner=new Scanner(System.in); Book book=new Book(); System.out.println("Enter book number:"); book.setId(new Scanner(System.in).nextLine()); System.out.println("Enter book name"); book.setBookname(new Scanner(System.in).nextLine()); System.out.println("Enter book category"); book.setBooktype(new Scanner(System.in).nextLine()); System.out.println("Enter book author"); book.setAuthor(new Scanner(System.in).nextLine()); System.out.println("Input Book Translator"); book.setTranslator(new Scanner(System.in).nextLine()); System.out.println("Input book publishing house"); book.setPublisher(new Scanner(System.in).nextLine()); System.out.println("Enter Book Pricing"); book.setPrice(new Scanner(System.in).nextDouble()); System.out.println("Enter book inventory quantity"); book.setStock(new Scanner(System.in).nextInt()); book.setPublish_time(new Date()); //Add information to the user set SystemData.BOOKLIST_SYSTEM.add(book); return true; } @Override public boolean del() { System.out.println("Enter the number of the book you want to delete:"); String num=new Scanner(System.in).nextLine(); ArrayList<Book>aBooks=SystemData.BOOKLIST_SYSTEM; for (int i = 0; i < aBooks.size(); i++) { if (num.equals(aBooks.get(i).getId())) { SystemData.BOOKLIST_SYSTEM.remove(i); System.out.println("Delete succeeded!"); return true; } } System.out.println("Deletion failed!"); return false; } @Override public int getCount() { return SystemData.BOOKLIST_SYSTEM.size(); } @Override public void getlistInfo() { ArrayList<Book>aBooks=SystemData.BOOKLIST_SYSTEM; if (aBooks.size()>0) { for(Book book:aBooks){ System.out.println(book.toString()); } }else { System.out.println("No information~"); } } @Override public boolean find() { System.out.println("Enter the number of the book you want to query:"); String num=new Scanner(System.in).nextLine(); ArrayList<Book>aBooks=SystemData.BOOKLIST_SYSTEM; for(Book book:aBooks){ if (num.equals(book.getId())) { System.out.println(book.toString()); return true; } } System.out.println("The book does not exist in the current book system!"); return false; } }
Borrow.java:
package com.zhumin.librarysystem.ben; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.Scanner; import com.zhumin.controller.SystemData; import com.zhumin.librarysystem.util.CreateSerialNumberUtil; import com.zhumin.service.IAction; /** * @ClassName Borrow * @Description Borrowing entity class * @author Doodle programmer shovel shit Officer * @date 2021 October 26 * */ public class Borrow implements IAction{ private String book_id; private String id;//Serial number private String reader_id; private String borrow_date; private String back_date; private boolean if_back; //Construction method public Borrow(String book_id, String id, String reader_id, String borrow_date, String back_date, boolean if_back) { this.book_id = book_id; this.id = id; this.reader_id = reader_id; this.borrow_date = borrow_date; this.back_date = back_date; this.if_back = if_back; } public Borrow() { } //get and set accessors for properties public String getBook_id() { return book_id; } public void setBook_id(String book_id) { this.book_id = book_id; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getReader_id() { return reader_id; } public void setReader_id(String reader_id) { this.reader_id = reader_id; } public String getBorrow_date() { return borrow_date; } public void setBorrow_date(String borrow_date) { this.borrow_date = borrow_date; } public String getBack_date() { return back_date; } public void setBack_date(String back_date) { this.back_date = back_date; } public boolean isIf_back() { return if_back; } public void setIf_back(boolean if_back) { this.if_back = if_back; } @Override public String toString() { return "Book number:" + book_id + ", Serial number:" + id + ", Reader number:" + reader_id + ", Borrowing time:" + borrow_date + ", Return time:" + back_date + ", Return:" + (if_back==true?"return":"Not returned") + ""; } @Override public boolean add() { Scanner scanner=new Scanner(System.in); System.out.println("Enter book number:"); String id=scanner.nextLine(); System.out.println("Enter reader number:"); String readerId=scanner.nextLine(); System.out.println("Enter borrowing time:"); String time1=scanner.nextLine(); System.out.println("Enter return time:"); String time2=scanner.nextLine(); boolean data=false; while (true) { System.out.println("Return the book:1:yes,2:no"); int if_data=scanner.nextInt(); if (if_data==1) { data=true; break; }else if (if_data==2) { data=false; break; }else { System.out.println("Please re-enter!"); } } Borrow borrow=new Borrow(id, CreateSerialNumberUtil.getSerialBorrowNumber(id), readerId,time1, time2,data); //Add the borrowed book information to the collection SystemData.BORROWLIST_SYSTEM.add(borrow); return false; } @Override public boolean del() { System.out.println("Enter the book number you want to delete the borrowing information:"); String num=new Scanner(System.in).nextLine(); ArrayList<Borrow>aBorrows=SystemData.BORROWLIST_SYSTEM; for (int i = 0; i < aBorrows.size(); i++) { if (aBorrows.get(i).getBook_id().equals(num)) { SystemData.BORROWLIST_SYSTEM.remove(i); System.out.println("Delete succeeded!"); return true; } } System.out.println("Deletion failed!"); return false; } @Override public int getCount() { return SystemData.BORROWLIST_SYSTEM.size(); } @Override public void getlistInfo() { ArrayList<Borrow>aBorrows=SystemData.BORROWLIST_SYSTEM; if (aBorrows.size()>0) { for(Borrow borrow:aBorrows){ System.out.println(borrow.toString()); } }else { System.out.println("No information~"); } } @Override public boolean find() { System.out.println("Enter the reader number of the borrowing information you want to query:"); String num=new Scanner(System.in).nextLine(); ArrayList<Borrow>aBorrows=SystemData.BORROWLIST_SYSTEM; for(Borrow borrow:aBorrows){ if (num.equals(borrow.getReader_id())) { System.out.println(borrow.toString()); return true; } } System.out.println("The reader information does not exist in the current book system!"); return false; } }
Reader.java:
package com.zhumin.librarysystem.ben; import java.util.ArrayList; import java.util.Date; import java.util.Scanner; import com.zhumin.controller.SystemData; import com.zhumin.service.IAction; /** * @ClassName Reader * @Description Reader entity class * @author Doodle programmer shovel shit Officer * @date 2021 October 26 * */ public class Reader implements IAction{ private String id="AA000001"; private String readername; private String readertype; private String sex; private int max_num; private int days_num; //Construction method public Reader(String id, String readername, String readertype, String sex, int max_num, int days_num) { this.id = id; this.readername = readername; this.readertype = readertype; this.sex = sex; this.max_num = max_num; this.days_num = days_num; } public Reader() { } //get()set() accessor for property public String getId() { return id; } public void setId(String id) { this.id = id; } public String getReadername() { return readername; } public void setReadername(String readername) { this.readername = readername; } public String getReadertype() { return readertype; } public void setReadertype(String readertype) { this.readertype = readertype; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getMax_num() { return max_num; } public void setMax_num(int max_num) { this.max_num = max_num; } public int getDays_num() { return days_num; } public void setDays_num(int days_num) { this.days_num = days_num; } @Override public String toString() { return "Reader number:" + id + ", Reader name:" + readername + ", Reader type:" + readertype + ", Reader gender:" + sex + ", Maximum number of books available:" + max_num + ", Borrowing days:" + days_num; } @Override public boolean add() { Reader reader=new Reader(); Scanner objScanner=new Scanner(System.in); System.out.println("Please enter the reader number:"); reader.setId(objScanner.nextLine()); System.out.println("Please enter the reader's name:"); reader.setReadername(objScanner.nextLine()); //System.out.println("please enter the reader type"); reader.setReadertype("Ordinary readers"); System.out.println("Please enter the reader gender:1:male,2:female"); while (true) { int num=objScanner.nextInt(); if (num==1) { reader.setSex("male"); break; }else if (num==2) { reader.setSex("female"); break; }else { System.out.println("Input error, please re-enter!"); } } //Use default values reader.setMax_num(5); reader.setDays_num(15); SystemData.READERLIST_SYSTEM.add(reader); return SystemData.CURRENT_READER!=null?true:false; } @Override public boolean del() { System.out.println("Enter the number of the reader you want to delete:"); String num=new Scanner(System.in).nextLine(); ArrayList<Reader>aReaders=SystemData.READERLIST_SYSTEM; for (int i = 0; i < aReaders.size(); i++) { if (aReaders.get(i).getId().equals(num)) { SystemData.READERLIST_SYSTEM.remove(i); System.out.println("Delete succeeded!"); return true; } } System.out.println("Deletion failed!"); return false; } @Override public int getCount() { // TODO Auto-generated method stub return SystemData.READERLIST_SYSTEM.size(); } @Override public void getlistInfo() { // TODO Auto-generated method stub ArrayList<Reader>aReaders=SystemData.READERLIST_SYSTEM; if (aReaders.size()>0) { for(Reader reader:aReaders){ System.out.println(reader.toString()); } }else { System.out.println("No information~"); } } @Override public boolean find() { System.out.println("Enter the number of the reader you want to query:"); String num=new Scanner(System.in).nextLine(); ArrayList<Reader>aReaders=SystemData.READERLIST_SYSTEM; for(Reader reader:aReaders){ if (num.equals(reader.getId())) { System.out.println(reader.toString()); return true; } } System.out.println("The reader information does not exist in the current book system!"); return false; } }
User.java:
package com.zhumin.librarysystem.ben; import java.util.ArrayList; import java.util.Date; import java.util.Scanner; import com.zhumin.controller.SystemData; import com.zhumin.librarysystem.util.CreateSerialNumberUtil; import com.zhumin.service.IAction; /** * @ClassName User * @Description User entity class * @author Doodle programmer shovel shit Officer * @date 2021 October 26 * */ public class User implements IAction{ private String id;//Serial number private String username; private String password; private boolean is_admin; //Construction method public User(String id, String username, String password, boolean is_admin) { this.id = id; this.username = username; this.password = password; this.is_admin = is_admin; } public User() { } //get()set() accessor for property public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean isIs_admin() { return is_admin; } public void setIs_admin(boolean is_admin) { this.is_admin = is_admin; } @Override public String toString() { return "User number:" + id + ", User name:" + username + ", User password:" + password + ", Administrator:" + (is_admin==true?"yes":"no" ); } @Override public boolean add() { User createUser=new User(); Scanner objScanner=new Scanner(System.in); System.out.println("Please enter the account number:"); createUser.setUsername(objScanner.nextLine()); System.out.println("Please input a password:"); createUser.setPassword(objScanner.nextLine()); createUser.setId(CreateSerialNumberUtil.getSerialNumber()); while(true){ System.out.println("Administrator,1 Means yes,2 Means No"); int num=objScanner.nextInt(); if (num==1) { createUser.setIs_admin(true); break; }else if (num==2) { createUser.setIs_admin(false); break; } System.out.println("Wrong format,Please re-enter!"); } SystemData.USERLIST_SYSTEM.add(createUser); return SystemData.CURRENT_USER!=null?true:false; } @Override public boolean del() { System.out.println("Enter the user account you want to delete:"); String num=new Scanner(System.in).nextLine(); ArrayList<User>aUsers=SystemData.USERLIST_SYSTEM; for (int i = 0; i < aUsers.size(); i++) { if (aUsers.get(i).getUsername().equals(num)) { SystemData.USERLIST_SYSTEM.remove(i); System.out.println("Delete succeeded!"); return true; } } System.out.println("Deletion failed!"); return false; } @Override public int getCount() { // TODO Auto-generated method stub return SystemData.USERLIST_SYSTEM.size(); } @Override public void getlistInfo() { // TODO Auto-generated method stub ArrayList<User>aUsers=SystemData.USERLIST_SYSTEM; if (aUsers.size()>0) { for(User user:aUsers){ System.out.println(user.toString()); } }else { System.out.println("No information~"); } } @Override public boolean find() { System.out.println("Enter the account number of the user you want to query:"); String num=new Scanner(System.in).nextLine(); User user=getUserInfoByUserName(num); if (user!=null) { System.out.println(user.toString()); return true; }else { System.out.println("The user information does not exist in the current book system!"); } return false; } //User Login public boolean userLogin(User user) { ArrayList<User>aUsers=SystemData.USERLIST_SYSTEM; for (User user2 : aUsers) { if (user2.getUsername().equals(user.getUsername())) { if (user2.getPassword().equals(user.getPassword())) { //Set the current user object to SystemData.CURRENT_USER=user2; return true; } } } return false; } //Get user information by user name public User getUserInfoByUserName(String userName) { ArrayList<User>aUsers=SystemData.USERLIST_SYSTEM; for(User user:aUsers){ if (userName.equals(user.getUsername())) { System.out.println(user.toString()); return user; } } return null; } }
5: The createserialnumberutil tool class is used to generate serial numbers
package com.zhumin.librarysystem.util; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; /** * @ClassName CreateSerialNumberUtil * @Description Generate serial number tool class * @author Doodle programmer shovel shit Officer * @date 2021 October 22 * */ public class CreateSerialNumberUtil { public static String getSerialNumber() { return new SimpleDateFormat("yyyyMMddhhmmss").format(new Date())+UUID.randomUUID().toString().replaceAll("-", ""); } public static String getSerialBorrowNumber(String id) { return new SimpleDateFormat("yyyyMMddhhmmss").format(new Date())+id; } }
7:IAction interface
package com.zhumin.service; /** * @Interface IAction * @Description Book system interface class * @author Doodle programmer shovel shit Officer * @date 2021 October 26 */ public interface IAction { public boolean add(); public boolean del(); public int getCount(); public void getlistInfo(); public boolean find(); }
8:Test class
3, Running effect and source code download address
Baidu online disk download address:
Link: https://pan.baidu.com/s/170GZr24ohtp-EiqXujSenw
Extraction code: 9999