Background of the project
In the era of information technology, efficiency and speed have become particularly important. High efficiency and speed will have better competitiveness and be more popular with customers. At the same time, online shopping is closely related to people's lives. The goods purchased by customers online need to be managed and distributed by logistics companies. Therefore, logistics management is particularly important in this process. How to efficiently and quickly manage warehouses? Commodity management directly affects the speed of logistics, thereby affecting customer satisfaction, which will directly affect the profit and loss of the company's interests.
Now there are also many mature online warehouse management systems that can manage warehouse products well, but not all warehouse companies have the same products, and those processes are not static, so these mature online warehouse management systems cannot adapt All warehouse companies. So I want to make a general-purpose warehouse management system with strong functions and simple functions to meet the basic needs of most warehouse companies. Although this cannot meet some specific requirements of these warehouse companies, all companies can make simple modifications on this basis And adding can satisfy your own warehouse management functions, so I think a basic and versatile warehouse management system is very meaningful. So this project is to make a warehouse management system for warehouse companies.
system structure
This project adopts the idea of front-end and back-end separation, and is divided into Vue front-end project and SpringBoot back-end project
The front end uses framework technologies such as Vue.js and Ant Vue Design, and the project is built by vue scaffolding, in which axios asynchronous request technology is used to initiate the request
The backend uses SpringBoot, Spring MVC, Spring Data JPA and other framework technologies. It is a project built by maven. The backend control layer uniformly adopts the Restful style to accept the requests sent by the frontend. The entire project uses the following components
- Lombok (quickly generate getters, setters, parameterized/non-parameterized construction methods)
- JWT (generate user login credentials)
- SpringSecurity (authority authentication framework)
The database uses Mysql to store data. To build the system, you only need to create the database, and the system will automatically create tables without manual creation.
system development tools
- I understand the idea
- VSCode
- Navicat Premium 15
System development environment
- JDK1.8
- Node.js
- Maven project management tool
Function overview
- Basic management: commodity management, business unit, employee management, warehouse management
- Sales management: sales billing, sales records
- Delivery management: apply for delivery, delivery list
- Transportation management: vehicle information, driver information
- Chart analysis: inbound analysis, outbound analysis (using echarts technology)
- System management: security settings, operator management, permission list
- Log management: login log, operation log
- Login registration: email login, email verification code login, user registration (by default, you will be a super administrator after registration)
function screenshot
login page
registration page
commodity management
Units
employee management
warehouse management
Sales billing
sales record
delivery list
Apply for delivery
vehicle management
driver information
login log
operation log
Function core code
User login function implementation:
package com.example.api.controller;
import com.example.api.exception.AccountAndPasswordError;
import com.example.api.model.dto.LoginDto;
import com.example.api.model.entity.Admin;
import com.example.api.model.entity.LoginLog;
import com.example.api.model.enums.Role;
import com.example.api.model.support.ResponseResult;
import com.example.api.repository.AdminRepository;
import com.example.api.service.AdminService;
import com.example.api.service.LoginLogService;
import com.example.api.utils.JwtTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/admin")
@Slf4j
public class AdminController {
//获取日志对象
Logger logger = LoggerFactory.getLogger(AdminController.class);
@Resource
private AdminService adminService;
@Resource
private AdminRepository adminRepository;
@Resource
private LoginLogService loginLogService;
@GetMapping("hasInit")
public boolean hasInit() {
return adminRepository.existsAdminByRoles(Role.ROLE_SUPER_ADMIN.getValue());
}
@PostMapping("/init")
public Admin init(@RequestBody Admin admin) throws Exception {
admin.setRoles(Role.ROLE_SUPER_ADMIN.getValue());
return adminService.save(admin);
}
@GetMapping("")
@PreAuthorize("hasAnyRole('ROLE_SUPER_ADMIN' ,'ROLE_ADMIN')")
public List<Admin> findAll() {
return adminService.findAll();
}
@DeleteMapping("")
@PreAuthorize("hasAnyRole('ROLE_SUPER_ADMIN' ,'ROLE_ADMIN')")
public void delete(String id) {
adminService.delete(id);
}
@PostMapping("")
@PreAuthorize("hasAnyRole('ROLE_SUPER_ADMIN' ,'ROLE_ADMIN')")
public Admin save(@RequestBody Admin admin) throws Exception {
return adminService.save(admin);
}
@PostMapping("/login")
public Map<String, Object> loginByEmail(String type, @RequestBody LoginDto dto, HttpServletRequest request) throws Exception {
Map<String, Object> map = new HashMap<>();
Admin admin = null;
String token = null;
try {
admin = type.equals("email") ? adminService.loginByEmail(dto) : adminService.loginByPassword(dto);
token = adminService.createToken(admin,
dto.isRemember() ? JwtTokenUtil.REMEMBER_EXPIRATION_TIME : JwtTokenUtil.EXPIRATION_TIME);
}catch (Exception e){
throw new Exception("邮箱或密码错误");
}finally {
loginLogService.recordLog(dto,admin,request);
}
map.put("admin", admin);
map.put("token", token);
return map;
}
@GetMapping("/sendEmail")
public ResponseResult sendEmail(String email) throws Exception {
Boolean flag = adminService.sendEmail(email);
ResponseResult res = new ResponseResult();
if (flag){
res.setMsg("发送成功,请登录邮箱查看");
}else {
res.setMsg("发送验证码失败,请检查邮箱服务");
}
res.setStatus(flag);
return res;
}
}
Log management function
1. Realization of login log function
Entity class LoginLog
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LoginLog {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
private String id;
//登录邮箱
private String email;
//登录状态
private Integer status;
//用户的IP地址
private String ip;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
//登录时间
private Date date;
//浏览器
private String browser;
}
Control layer Controller
@RestController
@RequestMapping("/api/admin")
@Slf4j
public class AdminController {
//获取日志对象
Logger logger = LoggerFactory.getLogger(AdminController.class);
@PostMapping("/login")
public Map<String, Object> loginByEmail(String type, @RequestBody LoginDto dto, HttpServletRequest request) throws Exception {
Map<String, Object> map = new HashMap<>();
Admin admin = null;
String token = null;
try {
admin = type.equals("email") ? adminService.loginByEmail(dto) : adminService.loginByPassword(dto);
token = adminService.createToken(admin,
dto.isRemember() ? JwtTokenUtil.REMEMBER_EXPIRATION_TIME : JwtTokenUtil.EXPIRATION_TIME);
}catch (Exception e){
throw new Exception("邮箱或密码错误");
}finally {
//记录登录日志
loginLogService.recordLog(dto,admin,request);
}
map.put("admin", admin);
map.put("token", token);
return map;
}
}
2. The function of recording the operation log is mainly realized by using Spring AOP technology, and the function of logging the control layer method containing the @Log annotation
Entity class SystemLog
package com.example.api.model.entity;
import com.example.api.model.enums.BusincessType;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.time.LocalDateTime;
@Entity
@Data
@NoArgsConstructor
public class SystemLog {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
//主键
private String id;
//账号
private String account;
//功能模块
private String module;
//操作类型
@Column(columnDefinition = "varchar(30) default 'LTD' not null")
private String busincessType;
//用户IP
@Column(columnDefinition = "varchar(40) default 'LTD' not null")
private String ip;
//请求方法
@Column(columnDefinition = "varchar(100) default 'LTD' not null")
private String method;
//操作时间
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime time;
}
The operation log notes are as follows:
@Target(ElementType.METHOD) //目标类型
@Retention(RetentionPolicy.RUNTIME) //作用范围
@Documented
public @interface Log {
/*
功能模块
*/
String moudle() default "";
/*
操作类型
*/
BusincessType type();
}
Business operation type enumeration class
package com.example.api.model.enums;
/*
业务操作类型
*/
public enum BusincessType {
OTHER("其他"), //其他
QUERY("查询"), //查询
INSERT("新增"), //新增
UPDATE("更新"), //更新
DELETE("删除"), //删除
EXPORT("导出"), //导出
FORCE("退出"); //强制退出
private BusincessType(String name){
this.name=name;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}