通訊錄-Java
目錄
文章目錄
內容
1、需求
現需要開發一個通訊錄功能,具體功能如下:
- A:顯示所有聯繫人
- B:查找某一位聯繫人
- C:添加聯繫人
- D:刪除聯繫人
- E:修改聯繫人
- F:結束當前所有操作
2、界面功能
- 剛進入cmd裏面的主界面 -》 6個小模塊
- A:顯示所有聯繫人
- B:查找某一位聯繫人
- C:添加聯繫人
- D:刪除聯繫人
- E:修改聯繫人
- F:結束當前所有操作
3、聯繫人
-
手機通訊錄聯繫人分類:
- 親人:relative
- 同事: colleague
- 朋友: friend
- 其他: other
-
手機通訊錄裏面所有的聯繫人底層都裝進一個集合對象裏面 -》 ArrayList
-
親人 同事 朋友 其他類型裏面共有的屬性:
- char initial;->首字母
- String name->聯繫人名字
- int age->聯繫人年齡
- char gender->聯繫人性
- long phone->手機號碼
- String zuoJi->座機號碼 = 區號 + 號碼
- 舉例: 0531-6661760
- 區號
- 0564: 六安
- 0531:濟南
- 0532:青島
- 號碼:7位數字
-
創建聯繫人對象的時候:
- szm name age gender phone是必填內容
- zuoJi可填可不填
-
座機
- 如果創建聯繫人對象的時候 用戶如果沒有提供zuoJi屬性值 ,那麼將zuoJi變量直接賦值爲"無座機號碼"
- 如果創建聯繫人對象的時候 用戶如果提供zuoJi屬性值了 ,那麼直接將zuoJi變量賦值爲用戶輸入的值
-
所有類裏面的屬性要求封裝
4、測試數據
朋友 x1 = new 朋友('Z',"張三",22,'男',15555555555L,"0531-6661760");
朋友 x2 = new 朋友('X',"小明",18,'男',18756789000L);
親人 x3 = new 親人('W',"王剛美",28,'女',18322009876L);
同事 x4 = new 同事('A',"阿磊",24,'男',15559501427L,"0564-6021117");
親人 x5 = new 親人('Z',"周凱",38,'男',18765432189L);
朋友 x6 = new 朋友('Z',"周s人",99,'男',17499990427L);
朋友 x7 = new 朋友('Z',"張三",22,'男',15555445555L);
//一個模塊一個模塊寫 寫完測試 測試通過寫下一個模塊
5、具體功能需要和實現
5.1、顯示所有聯繫人
如果用戶選擇是A 那麼有兩種選擇:
-
輸入校驗:
用戶可能輸進去的不是a/b 要求重新輸入
再次輸入的內容也需要校驗
直到用戶輸入一個正確的內容-
a:按照首字母進行顯示分類:
[效果如下:]A 阿磊 1555950427 W 王剛美 18322009876 X 小明 18756789000 Z 張三 15555555555 周凱 18765432189 ....
-
b:按照類別進行分類顯示:
[效果如下:]朋友 張三 15555555555 小明 18756789000 周s人 17499990427 張三 15555445555 親人 王剛美 18322009876 周凱 18765432189 同事 阿磊 1555950427 ...
-
5.2、查找某一位聯繫人
如果用戶選擇的是B:,cmd面板顯示下面這句話:
請問你是通過聯繫人名字進行精確查找/手機號碼模糊查詢
這裏用戶有兩種選擇:
-
用戶可以直接的輸入要查找聯繫人的名字
-
如果集合裏面沒有該用戶 直接顯示:
不好意思 當前用戶不存在 -
如果集合裏面有該用戶 需要將用戶的基本信息進行展示:
[效果如下:] [輸入]張三 [顯示] 用戶的基本信息: 聯繫人姓名:張三 聯繫人電話:15555555555 聯繫人座機號碼:0531-6661760 座機顯示城市:濟南 用戶的基本信息: 聯繫人姓名:張三 聯繫人電話:15555445555 聯繫人座機號碼:無座機號碼 座機顯示城市:未知城市
-
-
用戶還可以直接輸入一段電話號碼-》出現幾個數字就可以
-
如果集合裏面沒有用戶的號碼出現這幾個數字的 直接顯示:
不好意思 當前用戶不存在
-
如果查找到有這個用戶存在 顯示下面:
[效果如下:] [輸入]555555 [顯示] 用戶的基本信息: 聯繫人姓名:張三 聯繫人電話:15555555555 聯繫人座機號碼:0531-6661760 座機顯示城市:濟南
-
5.3、添加聯繫人
如果用戶選擇的是C:
-
需要進行輸入校驗:
- 選擇的分類可能不是親人 朋友 同事 默認其他
- 輸入的大寫首字母可能不是大寫首字母 是數字 是其他的漢字
- 註冊用戶名字的時候 應國家要求 關鍵字需要屏蔽(不能是敏感字…)
- 輸入的年齡非數字
- 性別選擇的不是A/B
- 輸入電話號碼的時候 非11爲數字 不是數字 不是以138 130 137 158 155 188. .開頭
- 座機可能不是按照 區號-號碼的形式傳進去的
- 座機號碼的區號只能出現0564 0531 0532
-
cmd裏面直接出現下面的內容:
請選擇聯繫人的分類A:親人 B:同事 C:朋友 D:其他 請輸入聯繫人名字大寫首字母: 請輸入聯繫人的姓名: 請輸入聯繫人的年齡: 請選擇聯繫人性別:A:男 B:女 請輸入聯繫人的電話: 請輸入聯繫人座機號碼(沒有請回復N):N/區號-座機號
-
當用戶依次輸入所有的信息之後 產生一個聯繫人,但是需要判斷集合裏面是否已經存在該用戶
-
如果存在(只要手機號碼相同就認爲是同一個聯繫人) ,那麼就不能繼續添加進通訊錄裏面
cmd裏面顯示:對不起 當前用戶已經存在 同一個用戶不能添加多次
-
如果不存在 將當前聯繫人添加進集合裏面
cmd裏面顯示:添加成功
-
5.4、刪除聯繫人
如果用戶選擇的是D:
-
直接在cmd裏面先以表的形式將所有聯繫人的信息顯示出來:
[效果如下:] 編號 姓名 年齡 電話 0 張三 22 155****5555 1 小明 18 187****9000 2 王剛美 28 183****9876 3 阿磊 24 155****4278 4 周凱 38 187****2189 5 周s人 99 174****0427 cmd裏面顯示:請問你要刪除聯繫人的編號:
-
輸入校驗:
-
需要對當前輸入的編碼進行判斷 是不是數字
- 如果不是 需要重新輸入(從新輸進去的內容還是需要進行輸入校驗),直到用戶輸入一個合法的數字
-
如果集合裏面有該編碼對象的元素 ,從集合裏面將當前編號的聯繫人刪除 並在cmd裏面顯示刪除成功
-
如果集合裏面沒有該編號對應的聯繫人
cmd裏面顯示:對不起 沒有該編碼對應的聯繫人
-
5.5、修改聯繫人
如果用戶選擇的是E:
-
輸入校驗
-
修改之後的姓名還是不能出現關鍵字
-
修改之後的電話號碼還是隻能以155 159…開頭
-
修改後的大寫首字母還是要判斷是否合法
-
可能用戶不是按照格式正確輸入 XXX-XXX-XXX(無論是修改前的輸入還是修改後的輸入格式需要正確)
[效果如下] 請輸入你要修改聯繫人的姓名大寫首字母 姓名 聯繫電話(中間-隔開):Z-張三-15555555555
-
-
找到集合裏面對應的聯繫人
-
如果集合裏面沒有該對象顯示:不好意思 當前聯繫人不存在
-
如果找到要修改的聯繫人 顯示一下提示語:
請輸入修改後的聯繫人的姓名大寫首字母 姓名 聯繫電話(中間-隔開):L-李四-18900000000
-
-
修改結束顯示修改成功
5.6、結束當前所有操作
如果用戶選擇的是F:
直接結束當前所有的操作 -》 break
6、完整代碼
-
聯繫人父類Contact代碼6-1:
package addressBook; /** * 聯繫人 * @author Administrator * */ public abstract class Contact { private char initial; // 首字母-修改 private String name; private int age; private char gender; private long phone; private String zuoji; // 座機-修改 public Contact() {} public Contact(char initial, String name, int age, char gender, long phone) { super(); this.initial = initial; this.name = name; this.age = age; this.gender = gender; this.phone = phone; } public Contact(char initial, String name, int age, char gender, long phone, String zuoji) { super(); this.initial = initial; this.name = name; this.age = age; this.gender = gender; this.phone = phone; this.zuoji = zuoji; } public char getInitial() { return initial; } public void setInitial(char initial) { this.initial = initial; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } public long getPhone() { return phone; } public void setPhone(long phone) { this.phone = phone; } public String getZuoji() { return zuoji; } public void setZuoji(String zuoji) { this.zuoji = zuoji; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Contact other = (Contact) obj; if (phone != other.phone) return false; return true; } @Override public String toString() { return this.name + "\t" + this.phone; } }
-
親人Relative代碼6-2:
package addressBook; public class Relative extends Contact { public Relative() { super(); // TODO Auto-generated constructor stub } public Relative(char initial, String name, int age, char gender, long phone, String zuoji) { super(initial, name, age, gender, phone, zuoji); // TODO Auto-generated constructor stub } public Relative(char initial, String name, int age, char gender, long phone) { super(initial, name, age, gender, phone); // TODO Auto-generated constructor stub } }
-
朋友Friend代碼6-3:
package addressBook; public class Friend extends Contact{ public Friend() {} public Friend(char initial, String name, int age, char gender, long phone, String zuoji) { super(initial, name, age, gender, phone, zuoji); } public Friend(char initial, String name, int age, char gender, long phone) { super(initial, name, age, gender, phone); } }
-
同事Colleague代碼6-4:
package addressBook; public class Colleague extends Contact { public Colleague() { super(); // TODO Auto-generated constructor stub } public Colleague(char initial, String name, int age, char gender, long phone, String zuoji) { super(initial, name, age, gender, phone, zuoji); // TODO Auto-generated constructor stub } public Colleague(char initial, String name, int age, char gender, long phone) { super(initial, name, age, gender, phone); // TODO Auto-generated constructor stub } }
-
其他類Other代碼6-5:
package addressBook; public class Other extends Contact { public Other() { super(); // TODO Auto-generated constructor stub } public Other(char initial, String name, int age, char gender, long phone, String zuoji) { super(initial, name, age, gender, phone, zuoji); // TODO Auto-generated constructor stub } public Other(char initial, String name, int age, char gender, long phone) { super(initial, name, age, gender, phone); // TODO Auto-generated constructor stub } }
-
通訊錄AddressBook類代碼6-6:
package addressBook; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Scanner; import java.util.TreeSet; import java.util.stream.Stream; /** * 通訊錄 * @author Administrator * */ public class AddressBook { private List<Contact> list; private Map<String, String> cities; private Scanner sc; private String errMsg = "輸入有誤!"; private static final int VERIFY_RANGE = 1; private static final int VERIFY_INITIAL = 2; private static final int VERIFY_NAME = 3; private static final int VERIFY_AGE = 4; private static final int VERIFY_PHONE = 5; private static final int VERIFY_ZUOJI = 6; private static final int VERIFY_NO = 7; public AddressBook() { list = new ArrayList<>(); } public AddressBook(List<Contact> list, Scanner sc, Map<String, String> cities) { this.list = list; this.sc = sc; this.cities = cities; } /** * 顯示所有聯繫人 */ public void showInfo() { this.printSeparatorLine("進入顯示所有聯繫人模塊"); String notice = "請輸入顯示方式:a(首字母)/b(類別)/c(索引表格)"; System.out.println(notice); String[] range = {"a", "b", "c"}; String type = this.ensureInput(this.errMsg + notice, range); if (type.trim().equalsIgnoreCase("a")) //a:按照首字母進行顯示分類: this.showInitial(); else if(type.trim().equalsIgnoreCase("b")) //b:按照類別進行分類顯示: this.showCategory(); // c:打印帶索引的表格數據 else this.printAll(); this.printSeparatorLine("離開顯示所有聯繫人模塊"); } /** * 按首字母顯示 */ public void showInitial() { TreeSet<Character> shouzimu = new TreeSet<>(); list.stream().forEach(n -> shouzimu.add(n.getInitial())); shouzimu.stream().forEach(s -> { System.out.println(s); list.stream().filter(x -> (x.getInitial() == s)).forEach(System.out::println); System.out.println(); }); } /** * 按類別顯示 */ public void showCategory() { System.out.println("\t朋友"); list.stream().filter(x -> (x instanceof Friend)).forEach(System.out::println); System.out.println(); System.out.println("\t親人"); list.stream().filter(x -> (x instanceof Relative)).forEach(System.out::println); System.out.println(); System.out.println("\t同事"); list.stream().filter(x -> (x instanceof Colleague)).forEach(System.out::println); System.out.println(); System.out.println("\t其他"); list.stream().filter(x -> (x instanceof Other)).forEach(System.out::println); System.out.println(); } /** * 打印分割線 */ public void printSeparatorLine(String str) { System.out.println("-----" + str + "-----"); } /** * 查找某個聯繫人模塊 */ public void find() { this.printSeparatorLine("進入查找聯繫人模塊"); String notice = "請輸入查找方式:a(聯繫人名字進行精確查找)/b(手機號碼模糊查詢)"; System.out.println(notice); String[] range = {"a", "b"}; String type = this.ensureInput(this.errMsg + notice, range); System.out.println("請輸入:"); String info = sc.nextLine(); Contact[] c = (type.trim().equalsIgnoreCase("a"))? this.findByName(info) : this.findByPhone(info); if(c.length == 0) System.out.println("不好意思當前用戶不存在"); else Stream.of(c).forEach(this::printOneInfo); this.printSeparatorLine("離開查找聯繫人模塊"); } /** * 通過人名查找 * @param name * @return */ public Contact[] findByName(String name) { return (this.list.stream().filter(s -> s.getName().equals(name)).toArray(Contact[]::new)); } /** * 通過手機號查找 * @param phone * @return */ public Contact[] findByPhone(String phone) { return (this.list.stream().filter(s -> ("" + s.getPhone()).contains(phone)).toArray(Contact[]::new)); } /** * 格式打印個人信息 * @param c */ public void printOneInfo(Contact c) { StringBuffer sb = new StringBuffer(); String zuoji = Objects.nonNull(c.getZuoji())? c.getZuoji(): "無座機號碼"; String city = Objects.nonNull(c.getZuoji())? this.cities.get(c.getZuoji().split("-")[0]): "未知城市"; sb.append("用戶的基本信息:\r\n") .append("聯繫人姓名:").append(c.getName()).append("\r\n") .append("聯繫人電話:").append(c.getPhone()).append("\r\n") .append("聯繫人座機號碼:").append(zuoji).append("\r\n") .append("座機顯示城市:").append(city).append("\r\n"); System.out.println(sb); } /** * 添加聯繫人模塊 */ public void addContact() { this.printSeparatorLine("進入添加聯繫人模塊"); // 創建聯繫人對象 Contact c = null; System.out.println("請選擇聯繫人的分類A:親人 B:同事 C:朋友 D:其他 "); String category = sc.nextLine(); switch(category) { case "親人": c = new Relative(); break; case "同事": c = new Colleague(); break; case "朋友": c = new Friend(); break; default: c = new Other(); } // 設置聯繫人屬性 // 設置首字母; String notice = "請輸入聯繫人名字大寫首字母:"; System.out.println(notice); String str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_INITIAL); c.setInitial(str.charAt(0)); // 設置姓名 notice = "請輸入聯繫人姓名:"; System.out.println(notice); str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_NAME); c.setName(str); // 設置年齡: notice = "請輸入聯繫人的年齡:"; System.out.println(notice); str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_AGE); c.setAge(Integer.parseInt(str)); // 設置性別 notice = "請選擇聯繫人性別:A:男 B:女"; System.out.println(notice); String[] range = {"a", "b"}; str = this.ensureInput(this.errMsg + notice, range); c.setGender(str.trim().equalsIgnoreCase("a")? '男': '女'); // 設置聯繫人電話 notice = "請輸入聯繫人的電話:"; System.out.println(notice); str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_PHONE); c.setPhone(Long.parseLong(str)); // 設置座機號碼 notice = "請輸入聯繫人座機號碼(沒有請回復N):N/區號-座機號"; System.out.println(notice); str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_ZUOJI); if(!str.equalsIgnoreCase("N")) c.setZuoji(str); // 新添加的聯繫人加入集合 this.list.add(c); System.out.println("添加成功"); this.printSeparatorLine("離開添加聯繫人模塊"); } /** * 刪除聯繫人模塊 */ public void deleteContact() { this.printSeparatorLine("刪除聯繫人模塊"); // 打印聯繫人列表 this.printAll(); String notice = "請問你要刪除聯繫人的編號: "; System.out.println(notice); String str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_NO); this.list.remove(Integer.parseInt(str)); System.out.println("刪除成功"); this.printSeparatorLine("離開刪除聯繫人模塊"); } /** * 表格打印 */ public void printAll() { System.out.println("編號\t姓名\t年齡\t電話"); for(int i = 0; i < this.list.size(); i++) { String str ="" + this.list.get(i).getPhone(); str = str.substring(0, 3) + "****" + str.substring(7); System.out.println(i + "\t" + this.list.get(i).getName() + "\t" + this.list.get(i).getAge() + "\t" + str); } } /** * 修改聯繫人模塊 */ public void updateContact() { this.printSeparatorLine("修改聯繫人模塊"); this.printAll(); String notice = "請問你要修改聯繫人的編號: "; System.out.println(notice); String str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_NO); int no = Integer.parseInt(str); // 輸入修改信息 String[] info = null; System.out.println("請輸入你要修改聯繫人的姓名大寫首字母-姓名-聯繫電話(中間-隔開): "); while(true) { str = sc.nextLine(); if(this.verifyUpdateInfo(str)) { info = str.split("-"); if(this.verifyInitial(info[0]) && this.verifyName(info[1]) && this.verifyPhone(info[2])) break; } System.out.println("輸入有誤!請輸入你要修改聯繫人的姓名大寫首字母 姓名 聯繫電話(中間-隔開): "); } this.list.get(no).setInitial(info[0].charAt(0)); this.list.get(no).setName(info[1]); this.list.get(no).setPhone(Long.parseLong(info[2])); System.out.println("修改成功"); this.printSeparatorLine("離開修改聯繫人模塊"); } /** * 首字母校驗 * @param str * @return */ public boolean verifyInitial(String str) { System.out.println("校驗首字母"); return Objects.nonNull(str) && str.matches("^[A-Z]$"); } /** * 手機號碼校驗 * @param str * @return */ public boolean verifyPhone(String str) { System.out.println("校驗手機號"); return Objects.nonNull(str) && str.matches("^1[358]\\d{9}$"); } /** * 校驗姓名 * @param str * @return */ public boolean verifyName(String str) { System.out.println("校驗姓名"); if(Objects.isNull(str)) return false; String keywords[] = {"SB", "2B", "BC"}; for(String n: keywords) { if(n.equals(str)) return false; } return true; } /** * 校驗年齡 * @param str * @return */ public boolean verifyAge(String str) { return Objects.nonNull(str) && str.matches("^\\d+$") && Integer.parseInt(str) > 0 && Integer.parseInt(str) <= 200; } /** * 校驗座機號碼 * @param str * @return */ public boolean verifyZuoJi(String str) { return Objects.nonNull(str) && str.matches("^05[36][124]-\\d{7}$|N|n"); } /** * 校驗編號 * @param str * @return */ public boolean verifyNo(String str) { return Objects.nonNull(str) && str.matches("^[0-9]+$") && Integer.parseInt(str) <= this.list.size() - 1; } /** * 修改聯繫人信息輸入校驗 * @param str * @return */ public boolean verifyUpdateInfo(String str) { System.out.println("校驗輸入信息"); return Objects.nonNull(str) && str.matches("^[A-Z]-.*-\\d+$"); } /** * 輸入校驗,確保輸入內容在range數組內 * @param errorMsg 錯誤提升 * @param range 可輸入範圍數組 * @return */ public String ensureInput(String errorMsg, String... range) { String type = null; while(true) { type = this.sc.nextLine(); boolean flag = false; // 輸入校驗: // 用戶可能輸進去的不是range中內容, 要求重新輸入 //再次輸入的內容也需要校驗 //直到用戶輸入一個正確的內容 for(String s: range) { if(s.equalsIgnoreCase(type)) { flag = true; break; } } if(flag) break; System.out.println(errorMsg); } return type; } public String ensureInput(String errorMsg, int verifyType) { String str = null; while(true) { str = sc.nextLine(); // if(str.matches("^[0-9]+$") && Integer.parseInt(str) <= this.list.size()) break; boolean flag = false; switch(verifyType) { case 2: if(this.verifyInitial(str)) flag = true; break; case 3: if(this.verifyName(str)) flag = true; break; case 4: if(this.verifyAge(str)) flag = true; break; case 5: if(this.verifyPhone(str)) flag = true; break; case 6: if(this.verifyZuoJi(str)) flag = true; break; default: } if(flag) break; System.out.println(errorMsg); } return str; } }
-
測試類TestAddressBook類:
package addressBook; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; public class TestAddressBook { public static void main(String[] args) { Friend x1 = new Friend('Z',"張三",22,'男',15555555555L,"0531-6661760"); Friend x2 = new Friend('X',"小明",18,'男',18756789000L); Relative x3 = new Relative('W',"王剛美",28,'女',18322009876L); Colleague x4 = new Colleague('A',"阿磊",24,'男',15559501427L,"0564-6021117"); Relative x5 = new Relative('Z',"周凱",38,'男',18765432189L); Friend x6 = new Friend('Z',"周樹人",99,'男',17499990427L); Friend x7 = new Friend('Z',"張三",22,'男',15555445555L); Other x8 = new Other('L',"李四",22,'男',15555445558L); List<Contact> list = new ArrayList<>(); Collections.addAll(list, x1, x2, x3, x4, x5, x6, x7, x8); Scanner sc = new Scanner(System.in); Map<String, String> cities = new HashMap<>(); cities.put("0531", "濟南"); cities.put("0532", "青島"); cities.put("0564", "六安"); AddressBook t = new AddressBook(list, sc, cities); // 顯示測試 // t.showInitial(); // t.showCategory(); // t.showInfo(); // 測試查找 // Contact[] c = t.findByName("張三"); // Contact[] c = t.findByPhone("5559"); // System.out.println(Arrays.toString(c)); // t.find(); // String str = "W-王五-13899999999"; // System.out.println(str.matches("^05[36][124]-\\d{7}$|N")); // t.addContact(); // t.printAll(); // t.deleteContact(); // t.printAll(); // System.out.println(str.matches("^[A-Z]-.*-\\d+$")); // t.updateContact(); // t.printAll(); System.out.println("-----歡迎進入通訊錄----"); Scanner s = new Scanner(System.in); while(true) { System.out.println("-----功能界面-----"); System.out.println("A:顯示所有聯繫人"); System.out.println("B:查找某一位聯繫人"); System.out.println("C:添加聯繫人"); System.out.println("D:刪除聯繫人"); System.out.println("E:修改聯繫人"); System.out.println("F:結束當前所有操作"); System.out.println("-----功能界面-----"); System.out.println("請輸入功能編號A-F:"); String str = s.nextLine(); boolean flag = false; switch(str.toLowerCase()) { case "a": t.showInfo(); break; case "b": t.find(); break; case "c": t.addContact(); break; case "d": t.deleteContact(); break; case "e": t.updateContact(); break; case "f": flag = true; break; default: } if(flag) break; } System.out.println("-----離開通訊錄----"); } } 測試結果:自己測試,有bug記得通知我
後記 :
本項目爲參考某馬視頻開發,相關視頻及配套資料可自行度娘或者聯繫本人。上面爲自己編寫的開發文檔,持續更新。歡迎交流,本人QQ:806797785
前端項目源代碼地址:https://gitee.com/gaogzhen/vue-leyou
後端JAVA源代碼地址:https://gitee.com/gaogzhen/JAVA