preface

Is graduation project really a demo? As the last campus project before work, the graduation project should be as close to the actual practice of the enterprise as possible. The business need not be very complicated, but it should be complete. In this period, students share with us how to develop an online course selection system, the demand is relatively simple. After system initialization, one admin super administrator account and three initialization roles are created by default:

  1. Super administrator role. Has permissions on all menus and buttons
  2. Teacher role. It has the rights to query account, add, delete, change and check course modules, select course records, departments and majors.
  3. Student roles. It has the rights of course inquiry, registration, withdrawal, department inquiry and major inquiry.

By default, all faculty and student accounts are created, and all departments and majors are created. Mainly is the management backstage, do you often need to allocate registered the account you still have to find super pipe distribution permissions, so makes little sense to register), when teachers create classes and can be set up registration, when registration opens, students can sign up for courses, the course registration deadline, students can drop out and register again. For concrete implementation, please see below ~~~

If you want source code, documents and video tutorials, please scan the code and add me to wechat. Here is an advertisement. The senior has many years of bat working experience and has been responsible for school and social recruitment interviews. If you are interested, you can write to me personally and I can provide resume guidance and internal promotion.

Engineering structure

Application layer

The above layer structure is taken from the Alibaba Java development manual. I have made some adjustments to it. The actual layer structure is as follows:

The domain model

  • DO (DataObject) : Transfers data source objects up through the DAO layer in one-to-one correspondence with the database table structure

  • BO (BusinessObject) : BusinessObject. An object that encapsulates the business logic output by the Service layer

  • VO (View Object) : Display layer objects, usually transmitted by the Web to the template rendering engine layer

    BO and VO domain models are divided into BoRequest (input model), BoResponse (output model), VoRequest (input model) and VoResponse (output model).

Technology stack

Front end: vue + Element

Backend: JDk1.8 + Springboot + Redis + mysql

Jurisdiction: the security + spring – the session

The system design

Table structure design

CREATE TABLE 'account' (' id 'bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', 'passport' varchar(16) NOT NULL COMMENT 'id ',' id 'varchar(6) NOT NULL COMMENT' id ', 'password' varchar(64) NOT NULL COMMENT 'password ',' status' int(11) NOT NULL DEFAULT '0' COMMENT 'user status ', 'role_id' bigint(20) NOT NULL COMMENT 'id ',' email 'varchar(32) NOT NULL COMMENT' id ', 'phone' varchar(16) NOT NULL COMMENT 'iD ',' address 'varchar(64) DEFAULT NULL COMMENT' iD ', 'sex' int(11) NOT NULL DEFAULT '0' COMMENT 'gender 0: female; 1: Male ', 'department_id' bigint(20) NOT NULL COMMENT 'department_id ',' major_id 'bigint(20) NOT NULL COMMENT' department_id ', 'description' varchar(128) DEFAULT NULL COMMENT 'Remarks ',' last_login_time 'bigint(20) DEFAULT NULL COMMENT' last login time ', 'create_time' bigint(20) NOT NULL DEFAULT '0' COMMENT 'update_time' bigint(20) DEFAULT NULL COMMENT 'update_time ', PRIMARY KEY (`id`), Mysql > InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT=' mysql 'Copy the code
CREATE TABLE `role` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'primary key'.`name` varchar(32) NOT NULL COMMENT 'Role Name'.`description` varchar(128) DEFAULT NULL COMMENT 'note'.`authorities` varchar(1024) NOT NULL COMMENT 'Permission List'.`create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Creation time'.`update_time` bigint(20) DEFAULT '0' COMMENT 'Update Time',
  PRIMARY KEY (`id`))ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='Role table'
Copy the code
CREATE TABLE `department` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'primary key'.`name` varchar(32) NOT NULL COMMENT 'Name of Department'.`introduction` text COMMENT 'introduction'.`create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Creation time'.`update_time` bigint(20) DEFAULT NULL COMMENT 'Update Time',
  PRIMARY KEY (`id`))ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='departments'
Copy the code
CREATE TABLE `major` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'primary key'.`name` varchar(32) NOT NULL COMMENT 'Name of Profession'.`introduction` text COMMENT 'introduction'.`department_id` bigint(20) NOT NULL COMMENT 'departments'.`create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Creation time'.`update_time` bigint(20) DEFAULT NULL COMMENT 'Update Time',
  PRIMARY KEY (`id`))ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='professional'
Copy the code
CREATE TABLE `course` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'primary key'.`name` varchar(64) NOT NULL COMMENT 'Course Name'.`credit` int(11) NOT NULL COMMENT 'credits'.`class_time` int(11) NOT NULL COMMENT 'class'.`teach_time` varchar(32) NOT NULL COMMENT 'School Hours'.`classroom` varchar(32) NOT NULL COMMENT 'classroom'.`account_id` bigint(20) NOT NULL COMMENT 'the teacher'.`department_id` bigint(20) NOT NULL COMMENT 'Department'.`major_id` bigint(20) NOT NULL COMMENT 'Major'.`type` int(11) NOT NULL COMMENT 'types; 1: Elective Courses 2: Compulsory Courses'.`require_type` int(11) NOT NULL COMMENT 'Restrictions on course selection; 1: Same department 2: Same major 3: Unlimited '.`available_amount` int(11) NOT NULL COMMENT 'Remaining number'.`registration_time` bigint(20) NOT NULL COMMENT 'Registration Time'.`registration_close_time` bigint(20) NOT NULL COMMENT 'Registration Deadline'.`introduction` text COMMENT 'introduction'.`create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Creation time'.`update_time` bigint(20) DEFAULT NULL COMMENT 'Update Time',
  PRIMARY KEY (`id`))ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8 COMMENT='course'
Copy the code
CREATE TABLE `course_record` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'primary key'.`course_id` bigint(20) NOT NULL COMMENT 'course'.`account_id` bigint(20) NOT NULL COMMENT 'students'.`create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Course Selection Time'.`update_time` bigint(20) DEFAULT NULL COMMENT 'Update Time',
  PRIMARY KEY (`id`))ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COMMENT='Course Selection Record'
Copy the code
CREATE TABLE `sys_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'primary key'.`passport` varchar(128) DEFAULT NULL COMMENT 'account'.`url` varchar(255) DEFAULT NULL COMMENT 'the request URL'.`method` varchar(255) DEFAULT NULL COMMENT 'Request method'.`params` varchar(2048) DEFAULT NULL COMMENT 'Request Parameters'.`ip` varchar(255) DEFAULT NULL COMMENT 'request IP'.`cost` bigint(20) DEFAULT NULL COMMENT 'Request Time in milliseconds'.`create_time` bigint(20) NOT NULL COMMENT 'Creation time',
  PRIMARY KEY (`id`))ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='System Log'
Copy the code

Interface design

The interface of the whole project adopts the restful style design that is popular on the Internet at present, and each interface and each parameter has detailed documentation. Because development in an enterprise is always a team effort, always a separate front and back end, you have to define the interfaces so that the front end and the back end can be developed simultaneously. Another way is to provide external interfaces. For example, your next-door team also wants to call the interface of your service, but your two schedules are in the same week. At this time, you have to define the interface to others first, and then develop it synchronously.

Running effect

System login

dashboard

Department management

The page menu, Query, Create, Edit, and Delete buttons all support separate permission assignment

Professional management

Each department can create multiple majors

Course management

Teachers will be assigned all rights of course management. They can create courses and set their departments and majors. As shown below, you can set “Course Selection restrictions”

  • This course is open only to students from the School of Computer Science and Technology.
  • “Same major” means that only students majoring in software engineering can register for this course;
  • “Unlimited” means that any student can sign up for the course;

“Remaining number” represents how many more people can enroll, which is actually a difficult point. For a popular course, hundreds of people apply for the course at the same time, and the remaining number is only 20. How to ensure that the number of applicants is not more than 20? At present, optimistic database lock is adopted.

“Registration time” means that the course selection can only start after the time, otherwise the registration button will not be displayed.

“Deadline” indicates how long the registration will last. When the deadline is reached, the registration button will be automatically cancelled and the course cannot be registered again. Students who are not satisfied with their course selection before the registration deadline may “drop the course” and choose another course

Course registration

Course record

A person can only sign up for a course once. Everyone’s registration results can be viewed in the Course Record Management menu.

In the “All Selected courses” TAB page, you can check the registration records of all students

In the “My course selection” TAB page, you can check the registration record of the current user. Support a variety of query conditions, for example, teachers can search for students who have signed up for their courses by “teacher name” and “course name”. Later, functions such as course sign-in, online examination and scoring can be added (this is not done by the seniors for the moment, it is also very simple to implement, you can try by yourself).

On the TAB page of “My Course Selection”, when the course registration has not been closed, you can “cancel the course”. After “cancel the course”, the course record will be deleted, and the “remaining number” of the course will be +1.

The drop

Log management

Log management is enabled for the administrator by default. All operations in the system are recorded, facilitating troubleshooting when the system is abnormal.

User management

By default, only the administrator has the permission to manage the user menu, and can create/edit users, assign user roles, and disable/enable users

Edit user information

Both teachers and students are users of the system, but teachers and students have different permissions. When creating an account, you must select “department” and “major”. In this way, if there are restrictions on course selection, it will be directly matched with the user’s department or major. If the match fails, it will not be allowed to select courses

Role management

The default option is only administrators have role management, the authority here is fine-grained permissions to button, each button can manage the permissions, if only allocated to the student course “query” permissions, but the student is a programmer, he want to ask for direct access to the course through the interface to modify interface, the backend is permission to check at this moment, Returns the “unauthorized” error code, then the front according to the “unauthorized” error code will be redirected to a 403 page (this is why only front-end validation is unsafe, the back-end must also have to check, this in the actual enterprise development also is such, have not junior drove to actual development experience with a small notebook to remember a, ha, ha, ha)

Permission to design

Permissions are implemented based on security and Spring-Session. Permissions can be divided into authentication and authorization. Authentication is actually login. When a user logs in, the account and password will be verified. Authorization refers to whether a user has the permission to access back-end resources. Each new user is assigned a role after creation. A role is actually a set of permissions, which can be understood as the permission to access back-end interfaces (resources).

Permissions design here is very flexible, fine-grained to the level of buttons, such as the course menu to add, delete, modify, query, students may access only queries of the course, unable to add and modify the course, even if it is modified through interface with direct access to the backend or new interface, the backend will also return authorization failed error, Because each back-end interface that requires permission is marked with permission tags, only users with resource permissions can access the interface.

Logging solution

Log using Lombok annotation + SLF4J + Log4j2 implementation scheme, based on the profile to achieve log configuration in multiple environments, because different environments have different log printing policies, for example, in the development environment, I may need to print logs to the console, and debug level logs are required for local development and debugging. Test environment may need to print to the log file, the online environment may need to print to a file at the same time send logs to the kafka and collected es, such as online deployed more machine after we check the log to a a machine to check the log, because all the es collection, we just need to log in to kibana to search, It’s very convenient. Kafka + ES + Kibana is one of the most popular logging solutions for Internet companies. If you can get your hands on it, you can build kafka, ES, kibana, and just add a few lines of configuration to your configuration file to create an enterprise-class logging solution (output to a log file by default).

The following are some key configurations. If you want to configure Kafka, you only need to configure the configuration in the tag

    
      
<Configuration status="WARN"  xmlns:xi="http://www.w3.org/2001/XInclude">
    <Properties>
        <Property name="LOG_FILE">system.log</Property>
        <Property name="LOG_PATH">./logs</Property>
        <Property name="PID">????</Property>
        <Property name="LOG_EXCEPTION_CONVERSION_WORD">%xwEx</Property>
        <Property name="LOG_LEVEL_PATTERN">%5p</Property>
        <Property name="LOG_DATE_FORMAT_PATTERN">yyyy-MM-dd HH:mm:ss.SSS</Property>
        <Property name="CONSOLE_LOG_PATTERN">%clr{%d{${LOG_DATE_FORMAT_PATTERN}}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{${sys:PID}}{magenta} %clr{---}{faint} % the CLR {[% 15.15 t]} {abbreviation} % CLR {% - 40.40 - c {1}} {cyan} % CLR {that} {abbreviation} % m % n ${sys: LOG_EXCEPTION_CONVERSION_WORD}</Property>
        <Property name="FILE_LOG_PATTERN">% d {${LOG_DATE_FORMAT_PATTERN}} ${LOG_LEVEL_PATTERN} ${sys: PID} [t] % % - 40.40 c {1} : % L: %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
    </Properties>
    <Appenders>
        <xi:include href="log4j2/file-appender.xml"/>
    </Appenders>
    <Loggers>
        <logger name="com.senior.book" level="info"/>
        <Root level="info">
            <AppenderRef ref="FileAppender"/>
        </Root>
    </Loggers>
</Configuration>
Copy the code

Service monitoring

The monitoring of services is implemented based on the Actuator + Prometheus + Grafana, and the code incursion is very small. Only the dependencies need to be added in THE POM. Data Dashboard can be set up by yourself, you can also go to the Dashboard market to download the template you want, in short, this is completely depends on hands-on ability, we play by ourselves ~~~

		<! -- Service Monitoring -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
        </dependency>
Copy the code