简单的Java_Swing小项目

火影  论坛元老 | 2024-12-17 00:02:52 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1025|帖子 1025|积分 3075

Swing小项目

无需任何额外设置,直接可以在eclipse用
非常简单的文件结构

简单的登录界面

进去后就大概是这么个样子

很久从前写的了,我就不一一打开展示了。内容和无UI版本差不多,只是用简单的Swing实现了界面化操作
数据是可以保存在根目次下的data.bat文件中,退出重新登录,之前录入的数据也是存在的。
Main.java
  1. package swing;
  2. import javax.swing.*;
  3. import java.io.*;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. public class Main {
  7.     private static final String FILE_PATH = "data.dat";//static修饰符表示变量FILE_PATH是类级别的,而不是实例(对象)级别的。即不需要创建Main类的对象就可以访问FILE_PATH,否则需要通过Main类的对象来访问,final修饰符表示变量初始化后就无法更改
  8.     private static List<Course> courseList = new ArrayList<>();
  9.     private static List<Teacher> teacherList = new ArrayList<>();
  10.     private static List<Student> studentList = new ArrayList<>();
  11.     public static void main(String[] args) {
  12.         loadData();
  13.         SwingUtilities.invokeLater(() -> {
  14.             new LoginFrame();
  15.         });
  16.     }
  17.     public static void loadData() {
  18.         try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data.dat"))) {
  19.             courseList = (List<Course>) ois.readObject();//读取是反序列化的过程,将文件存储的字节流提取出来还原到对象中
  20.             teacherList = (List<Teacher>) ois.readObject();
  21.             studentList = (List<Student>) ois.readObject();
  22.             JOptionPane.showMessageDialog(null, "Data loaded successfully.");
  23.         } catch (EOFException e) {
  24.             JOptionPane.showMessageDialog(null, "Data file not found, initializing default data.");
  25.         } catch (Exception e) {
  26.             e.printStackTrace();
  27.         }
  28.     }
  29.     public static void saveData() {
  30.         try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.dat"))) {
  31.             oos.writeObject(courseList);//写入是序列化的过程,将数据转化为字节流的形式存储起来
  32.             oos.writeObject(teacherList);
  33.             oos.writeObject(studentList);
  34.             JOptionPane.showMessageDialog(null, "Data saved successfully.");
  35.         } catch (Exception e) {
  36.             e.printStackTrace();
  37.         }
  38.     }
  39.     public static List<Course> getCourseList() {
  40.         return courseList;
  41.     }
  42.     public static List<Teacher> getTeacherList() {
  43.         return teacherList;
  44.     }
  45.     public static List<Student> getStudentList() {
  46.         return studentList;
  47.     }
  48. }
复制代码
AdminMenu.java
  1. package swing;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.util.Comparator;
  7. public class AdminMenu extends JFrame {
  8.     public AdminMenu() {
  9.         setTitle("管理员菜单");
  10.         setSize(600, 400); // 调整窗口大小
  11.         setLayout(new GridLayout(8, 1));
  12.         JButton addCourseButton = new JButton("添加课程");
  13.         JButton deleteCourseButton = new JButton("删除课程");
  14.         JButton sortCoursesButton = new JButton("按照选课人数排序");
  15.         JButton modifyTeacherButton = new JButton("修改授课教师");
  16.         JButton restorePasswordsButton = new JButton("恢复密码");
  17.         JButton viewListsButton = new JButton("查看课程、教师和学生列表");
  18.         JButton addTeacherButton = new JButton("添加教师");
  19.         JButton addStudentButton = new JButton("添加学生");
  20.         JButton deleteTeacherButton = new JButton("删除教师");
  21.         JButton deleteStudentButton = new JButton("删除学生");
  22.         add(addCourseButton);
  23.         add(deleteCourseButton);
  24.         add(sortCoursesButton);
  25.         add(modifyTeacherButton);
  26.         add(restorePasswordsButton);
  27.         add(viewListsButton);
  28.         add(addTeacherButton);
  29.         add(addStudentButton);
  30.         add(deleteTeacherButton);
  31.         add(deleteStudentButton);
  32.         addCourseButton.addActionListener(e -> addCourse());
  33.         deleteCourseButton.addActionListener(e -> deleteCourse());
  34.         sortCoursesButton.addActionListener(e -> sortCourses());
  35.         modifyTeacherButton.addActionListener(e -> modifyTeacher());
  36.         restorePasswordsButton.addActionListener(e -> restorePasswords());
  37.         viewListsButton.addActionListener(e -> viewLists());
  38.         addTeacherButton.addActionListener(e -> addTeacher());
  39.         addStudentButton.addActionListener(e -> addStudent());
  40.         deleteTeacherButton.addActionListener(e -> deleteTeacher());
  41.         deleteStudentButton.addActionListener(e -> deleteStudent());
  42.         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  43.         setVisible(true);
  44.     }
  45.     private void addCourse() {
  46.         String courseName = JOptionPane.showInputDialog("输入课程名称:");
  47.         String isMandatoryInput = JOptionPane.showInputDialog("输入是否为必修课 (yes/no):");
  48.         boolean isMandatory = isMandatoryInput.equalsIgnoreCase("yes");
  49.         Teacher selectedTeacher = (Teacher) JOptionPane.showInputDialog(null,
  50.             "选择任课教师:", "添加课程",
  51.             JOptionPane.QUESTION_MESSAGE, null,
  52.             Main.getTeacherList().toArray(),
  53.             Main.getTeacherList().get(0));
  54.         Course newCourse = new Course(courseName, isMandatory, selectedTeacher);
  55.         if (!isMandatory) {
  56.             String maxEnrollmentInput = JOptionPane.showInputDialog("输入最大选课人数:");
  57.             newCourse.maxEnrollment = Integer.parseInt(maxEnrollmentInput); // 仅对选修课设置最大人数
  58.         }
  59.         Main.getCourseList().add(newCourse);
  60.         Main.saveData();
  61.         JOptionPane.showMessageDialog(this, "课程添加成功");
  62.     }
  63.     private void deleteCourse() {
  64.         String courseName = JOptionPane.showInputDialog("输入要删除的课程名称:");
  65.         Main.getCourseList().removeIf(course -> course.getName().equals(courseName));
  66.         Main.saveData();
  67.         JOptionPane.showMessageDialog(this, "课程删除成功");
  68.     }
  69.     private void sortCourses() {
  70.         Main.getCourseList().sort(Comparator.comparingInt(Course::getCurrentEnrollment).reversed());
  71.         JOptionPane.showMessageDialog(this, "课程已按选课人数排序");
  72.     }
  73.     private void modifyTeacher() {
  74.         String teacherName = JOptionPane.showInputDialog("输入教师用户名:");
  75.         String newCourseName = JOptionPane.showInputDialog("输入新的课程名称:");
  76.         
  77.         // 修改授课教师的逻辑
  78.         // 这里可以扩展,以便选择具体的课程和教师进行修改
  79.         JOptionPane.showMessageDialog(this, "授课教师修改成功");
  80.     }
  81.     private void restorePasswords() {
  82.         for (Teacher teacher : Main.getTeacherList()) {
  83.             teacher.changePassword("123456");
  84.         }
  85.         for (Student student : Main.getStudentList()) {
  86.             student.changePassword("123456");
  87.         }
  88.         Main.saveData();
  89.         JOptionPane.showMessageDialog(this, "所有密码已恢复为初始密码");
  90.     }
  91.     private void viewLists() {
  92.         StringBuilder list = new StringBuilder("课程列表:\n");
  93.         for (Course course : Main.getCourseList()) {
  94.             String courseType = course.getCourseType(); // 获取课程类型
  95.             String teacherName = course.getTeacher().getUsername(); // 获取任课教师
  96.             String enrollmentInfo = course.isMandatory() ? "" : ", 选课人数: " + course.getCurrentEnrollment() + "/" + course.getMaxEnrollment();
  97.             
  98.             list.append(String.format("课程名称: %s, 类型: %s, 任课教师: %s%s\n",
  99.                 course.getName(), courseType, teacherName, enrollmentInfo));
  100.         }
  101.         list.append("教师列表:\n");
  102.         for (Teacher teacher : Main.getTeacherList()) {
  103.             list.append(teacher.getUsername()).append("\n");
  104.         }
  105.         
  106.         list.append("学生列表:\n");
  107.         for (Student student : Main.getStudentList()) {
  108.             list.append(student.getUsername()).append("\n");
  109.         }
  110.         
  111.         JOptionPane.showMessageDialog(this, list.toString());
  112.     }
  113.     private void addTeacher() {
  114.         String teacherName = JOptionPane.showInputDialog("输入教师用户名:");
  115.         String teacherPassword = "123456"; // 默认密码
  116.         Teacher newTeacher = new Teacher(teacherName, teacherPassword);
  117.         Main.getTeacherList().add(newTeacher);
  118.         Main.saveData();
  119.         JOptionPane.showMessageDialog(this, "教师添加成功");
  120.     }
  121.     private void addStudent() {
  122.         String studentName = JOptionPane.showInputDialog("输入学生用户名:");
  123.         String studentPassword = "123456"; // 默认密码
  124.         Student newStudent = new Student(studentName, studentPassword);
  125.         Main.getStudentList().add(newStudent);
  126.         Main.saveData();
  127.         JOptionPane.showMessageDialog(this, "学生添加成功");
  128.     }
  129.     private void deleteTeacher() {
  130.         String teacherName = JOptionPane.showInputDialog("输入要删除的教师用户名:");
  131.         Main.getTeacherList().removeIf(teacher -> teacher.getUsername().equals(teacherName));
  132.         Main.saveData();
  133.         JOptionPane.showMessageDialog(this, "教师删除成功");
  134.     }
  135.     private void deleteStudent() {
  136.         String studentName = JOptionPane.showInputDialog("输入要删除的学生用户名:");
  137.         Main.getStudentList().removeIf(student -> student.getUsername().equals(studentName));
  138.         Main.saveData();
  139.         JOptionPane.showMessageDialog(this, "学生删除成功");
  140.     }
  141. }
复制代码
Course.java
  1. package swing;
  2. import java.io.Serializable;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. public class Course implements Serializable {
  6.     private static final long serialVersionUID = 1L;
  7.     private String name;
  8.     private boolean isMandatory; // true表示必修课
  9.     protected int maxEnrollment; // 最大选课人数,选修课时有效
  10.     private List<Student> enrolledStudents;
  11.     private Teacher teacher;
  12.     public Course(String name, boolean isMandatory, Teacher teacher) {
  13.         this.name = name;
  14.         this.isMandatory = isMandatory;
  15.         this.enrolledStudents = new ArrayList<>();
  16.         this.teacher = teacher;
  17.         this.maxEnrollment = isMandatory ? Integer.MAX_VALUE : 30; // 选修课默认最大人数
  18.     }
  19.     public String getName() {
  20.         return name;
  21.     }
  22.     public boolean isMandatory() {
  23.         return isMandatory;
  24.     }
  25.     public int getCurrentEnrollment() {
  26.         return enrolledStudents.size();
  27.     }
  28.     public List<Student> getEnrolledStudents() {
  29.         return enrolledStudents;
  30.     }
  31.     public Teacher getTeacher() {
  32.         return teacher;
  33.     }
  34.     public void enrollStudent(Student student) {
  35.         if (isMandatory || enrolledStudents.size() < maxEnrollment) {
  36.             enrolledStudents.add(student);
  37.         }
  38.     }
  39.    
  40.    
  41.     public String getCourseType() {
  42.         return isMandatory ? "必修课" : "选修课";
  43.     }
  44.     public int getMaxEnrollment() {
  45.         return maxEnrollment;
  46.     }
  47. }
复制代码
LoginFrame.java
  1. package swing;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. public class LoginFrame extends JFrame {
  7.         private static final long serialVersionUID = 1L; // 添加serialVersionUID
  8.     private JTextField usernameField;
  9.     private JPasswordField passwordField;
  10.     private JButton togglePasswordButton;
  11.     public LoginFrame() {
  12.         setTitle("登录");
  13.         setSize(300, 150);
  14.         setLayout(new GridLayout(3, 2));
  15.         add(new JLabel("用户名:"));
  16.         usernameField = new JTextField();
  17.         add(usernameField);
  18.         add(new JLabel("密码:"));
  19.         passwordField = new JPasswordField();
  20.         add(passwordField);
  21.         
  22.         togglePasswordButton = new JButton("显示密码");
  23.         add(togglePasswordButton);
  24.         JButton loginButton = new JButton("登录");
  25.         add(loginButton);
  26.         loginButton.addActionListener(new ActionListener() {
  27.             @Override
  28.             public void actionPerformed(ActionEvent e) {
  29.                 login();
  30.             }
  31.         });
  32.         
  33.      // Add action listener for the button
  34.         togglePasswordButton.addActionListener(new ActionListener() {
  35.             @Override
  36.             public void actionPerformed(ActionEvent e) {
  37.                 togglePasswordVisibility();
  38.             }
  39.         });
  40.         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  41.         setVisible(true);
  42.     }
  43.    
  44.     private void togglePasswordVisibility() {
  45.     // 检查密码框当前的回显字符模式
  46.     if (passwordField.getEchoChar() == '\u0000') {  // '\u0000' 表示没有字符被回显(密码可见)
  47.         passwordField.setEchoChar('*');  // 重置回显字符为 '*',隐藏密码
  48.         togglePasswordButton.setText("显示密码");
  49.     } else {
  50.         passwordField.setEchoChar((char) 0);  // 设置回显字符为 0,使密码明文显示
  51.         togglePasswordButton.setText("隐藏密码");
  52.     }
  53. }
  54.     private void login() {
  55.         String username = usernameField.getText();
  56.         String password = new String(passwordField.getPassword());
  57.         if (username.equals("admin") && password.equals("admin123")) {
  58.             new AdminMenu();
  59.             dispose();
  60.         } else {
  61.             // Check other user types
  62.             for (Teacher teacher : Main.getTeacherList()) {
  63.                 if (teacher.getUsername().equals(username) && teacher.getPassword().equals(password)) {
  64.                     new TeacherMenu(teacher);
  65.                     dispose();
  66.                     return;
  67.                 }
  68.             }
  69.             for (Student student : Main.getStudentList()) {
  70.                 if (student.getUsername().equals(username) && student.getPassword().equals(password)) {
  71.                     new StudentMenu(student);
  72.                     dispose();
  73.                     return;
  74.                 }
  75.             }
  76.             JOptionPane.showMessageDialog(this, "用户名或密码错误");
  77.         }
  78.     }
  79. }
复制代码
Student.java
  1. package swing;
  2. import java.io.Serializable;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. public class Student implements Serializable {
  6.     private String username;
  7.     private String password;
  8.     private List<Course> selectedCourses; // 存储所选课程的列表
  9.     public Student(String username, String password) {
  10.         this.username = username;
  11.         this.password = password;
  12.         this.selectedCourses = new ArrayList<>(); // 初始化课程列表
  13.     }
  14.     // Getter方法
  15.     public String getUsername() {
  16.         return username;
  17.     }
  18.     public String getPassword() {
  19.         return password;
  20.     }
  21.     public List<Course> getSelectedCourses() {
  22.         return selectedCourses;
  23.     }
  24.     public void addCourse(Course course) {
  25.         if (!selectedCourses.contains(course)) {
  26.             selectedCourses.add(course);
  27.         }
  28.     }
  29.     // 修改密码的方法
  30.     public void changePassword(String newPassword) {
  31.         this.password = newPassword;
  32.     }
  33.     // 重写 toString() 方法
  34.     @Override
  35.     public String toString() {
  36.         return username; // 返回学生的用户名
  37.     }
  38. }
复制代码
StudentMenu.java
  1. package swing;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. public class StudentMenu extends JFrame {
  7.     private static final long serialVersionUID = 1L;
  8.     private Student student;
  9.     public StudentMenu(Student student) {
  10.         this.student = student;
  11.         setTitle("学生菜单");
  12.         setSize(400, 300);
  13.         setLayout(new GridLayout(4, 1));
  14.         JButton changePasswordButton = new JButton("修改密码");
  15.         JButton viewCoursesButton = new JButton("查看所上课程");
  16.         JButton enrollButton = new JButton("选修课程");
  17.         add(changePasswordButton);
  18.         add(viewCoursesButton);
  19.         add(enrollButton);
  20.         changePasswordButton.addActionListener(e -> changePassword());
  21.         viewCoursesButton.addActionListener(e -> viewCourses());
  22.         enrollButton.addActionListener(e -> enrollCourse());
  23.         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  24.         setVisible(true);
  25.     }
  26.     private void changePassword() {
  27.         String newPassword = JOptionPane.showInputDialog("输入新密码:");
  28.         student.changePassword(newPassword);
  29.         Main.saveData();
  30.         JOptionPane.showMessageDialog(this, "密码已修改");
  31.     }
  32.     private void viewCourses() {
  33.         StringBuilder courseList = new StringBuilder("所上课程:\n");
  34.         // 添加必修课程
  35.         for (Course course : Main.getCourseList()) {
  36.             if (course.isMandatory()) {
  37.                 courseList.append(course.getName()).append(" - 任课教师: ").append(course.getTeacher().getUsername()).append("\n");
  38.             }
  39.         }
  40.         // 添加选修课程
  41.         for (Course course : student.getSelectedCourses()) {
  42.             courseList.append(course.getName()).append(" - 任课教师: ").append(course.getTeacher().getUsername()).append("\n");
  43.         }
  44.         JOptionPane.showMessageDialog(this, courseList.toString());
  45.     }
  46.     private void enrollCourse() {
  47.         String courseName = JOptionPane.showInputDialog("输入要选修的课程名称:");
  48.         for (Course course : Main.getCourseList()) {
  49.             if (course.getName().equals(courseName)) {
  50.                 // 验证选课人数
  51.                 if (course.isMandatory() || course.getCurrentEnrollment() < course.getMaxEnrollment()) {
  52.                     selectElectiveCourse(course);
  53.                     return;
  54.                 } else {
  55.                     JOptionPane.showMessageDialog(this, "课程已满");
  56.                 }
  57.             }
  58.         }
  59.         JOptionPane.showMessageDialog(this, "课程不存在");
  60.     }
  61.     // 选修课程的方法
  62.     private void selectElectiveCourse(Course course) {
  63.         if (!course.isMandatory()) {
  64.             student.addCourse(course); // 将选修课程添加到学生的课程列表中
  65.             JOptionPane.showMessageDialog(this, "选修课程成功!");
  66.             Main.saveData(); // 保存数据
  67.         }
  68.     }
  69. }
复制代码
Teacher.java
  1. package swing;
  2. import java.io.Serializable;
  3. public class Teacher implements Serializable {
  4.     private String username;
  5.     private String password;
  6.     public Teacher(String username, String password) {
  7.         this.username = username;
  8.         this.password = password;
  9.     }
  10.     // Getter方法
  11.     public String getUsername() {
  12.         return username;
  13.     }
  14.     public String getPassword() {
  15.         return password;
  16.     }
  17.     // 修改密码的方法
  18.     public void changePassword(String newPassword) {
  19.         this.password = newPassword;
  20.     }
  21.     // 重写 toString() 方法
  22.     @Override
  23.     public String toString() {
  24.         return username; // 返回教师的用户名
  25.     }
  26. }
复制代码
TeacherMenu.java
  1. package swing;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. public class TeacherMenu extends JFrame {
  5.     private static final long serialVersionUID = 1L;
  6.     private Teacher teacher;
  7.     public TeacherMenu(Teacher teacher) {
  8.         this.teacher = teacher;
  9.         setTitle("教师菜单");
  10.         setSize(400, 300);
  11.         setLayout(new GridLayout(5, 1)); // 增加一行
  12.         JButton changePasswordButton = new JButton("修改密码");
  13.         JButton viewCoursesButton = new JButton("查看所授课程");
  14.         JButton viewStudentsButton = new JButton("查看上课学生");
  15.         JButton viewCourseStudentsButton = new JButton("查看某门课程的学生");
  16.         add(changePasswordButton);
  17.         add(viewCoursesButton);
  18.         add(viewStudentsButton);
  19.         add(viewCourseStudentsButton);
  20.         changePasswordButton.addActionListener(e -> changePassword());
  21.         viewCoursesButton.addActionListener(e -> viewCourses());
  22.         viewStudentsButton.addActionListener(e -> viewStudentsInCourses());
  23.         viewCourseStudentsButton.addActionListener(e -> viewStudentsInSpecificCourse());
  24.         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  25.         setVisible(true);
  26.     }
  27.     private void changePassword() {
  28.         String newPassword = JOptionPane.showInputDialog("输入新密码:");
  29.         teacher.changePassword(newPassword);
  30.         Main.saveData();
  31.         JOptionPane.showMessageDialog(this, "密码已修改");
  32.     }
  33.     private void viewCourses() {
  34.         StringBuilder mandatoryCourses = new StringBuilder("必修课:\n");
  35.         StringBuilder electiveCourses = new StringBuilder("选修课:\n");
  36.         
  37.         for (Course course : Main.getCourseList()) {
  38.             if (course.isMandatory()) {
  39.                 mandatoryCourses.append(String.format("课程名称: %s, 任课教师: %s\n",
  40.                     course.getName(), course.getTeacher().getUsername()));
  41.             } else {
  42.                 electiveCourses.append(String.format("课程名称: %s, 任课教师: %s, 选课人数: %d/%d\n",
  43.                     course.getName(), course.getTeacher().getUsername(),
  44.                     course.getCurrentEnrollment(), course.getMaxEnrollment()));
  45.             }
  46.         }
  47.         
  48.         StringBuilder courseListDisplay = new StringBuilder();
  49.         courseListDisplay.append(mandatoryCourses).append("\n").append(electiveCourses);
  50.         
  51.         JOptionPane.showMessageDialog(this, courseListDisplay.toString());
  52.     }
  53.     private void viewStudentsInCourses() {
  54.         StringBuilder studentList = new StringBuilder("上课学生名单:\n");
  55.         boolean hasCourses = false;
  56.         
  57.         for (Course course : Main.getCourseList()) {
  58.             if (course.getTeacher().equals(teacher)) {
  59.                 hasCourses = true;
  60.                 studentList.append("课程: ").append(course.getName()).append("\n");
  61.                 for (Student student : course.getEnrolledStudents()) {
  62.                     studentList.append(" - ").append(student.getUsername()).append("\n");
  63.                 }
  64.             }
  65.         }
  66.         
  67.         if (!hasCourses) {
  68.             studentList.append("该教师没有教授任何课程。");
  69.         }
  70.         
  71.         JOptionPane.showMessageDialog(this, studentList.toString());
  72.     }
  73.     private void viewStudentsInSpecificCourse() {
  74.         String courseName = JOptionPane.showInputDialog("输入课程名称:");
  75.         StringBuilder studentList = new StringBuilder("学生名单:\n");
  76.         boolean foundCourse = false;
  77.         for (Course course : Main.getCourseList()) {
  78.             if (course.getName().equals(courseName) && course.getTeacher().equals(teacher)) {
  79.                 foundCourse = true;
  80.                 for (Student student : course.getEnrolledStudents()) {
  81.                     studentList.append(student.getUsername()).append("\n");
  82.                 }
  83.                 break;
  84.             }
  85.         }
  86.         
  87.         if (!foundCourse) {
  88.             studentList.append("没有找到该课程或该课程不属于您。");
  89.         }
  90.         
  91.         JOptionPane.showMessageDialog(this, studentList.toString());
  92.     }
  93. }
复制代码
module-info.java
  1. module experiment_2 {
  2.         requires java.desktop;
  3. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

火影

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表