前言
现在很多公司系统都是前后端分离的,Java后端人员想要自己开发一套系统,有时候还整不了,还挺费劲。themlef+layui 框架就是为后端人员快速入门前端开发而生的,启动Springboot后整个前后端系统就起来了,可以非常快速的开发一套系统;
本篇文章主要讲解仓库管理系统如何实现的。
一、仓库管理系统拆解
整个系统主要有登录功能、系统管理、基础管理、进货管理、销售管理、其他管理
二、主要界面
1、登录界面
2、登录后首页
3、客户管理
4、系统管理=》部门管理
5、系统管理=》菜单管理
这里可以自定义菜单,非常智能方便
三、主要代码
1.配置maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.dev.warehouse</groupId>
<artifactId>warehouseSys</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>warehouseSys</name>
<description>仓库管理系统</description>
<properties>
<java.version>1.8</java.version>
<mybatisplus.version>3.2.0</mybatisplus.version>
<druid.version>1.1.20</druid.version>
<shiro.version>1.4.0</shiro.version>
<log4j.version>1.2.17</log4j.version>
<hutool.version>4.6.8</hutool.version>
<pinyin4j.version>2.5.1</pinyin4j.version>
<fastjson.version>1.2.62</fastjson.version>
</properties>
<dependencies>
<!--面向切面-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--mybatisplus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<!--mybatisplus代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.29</version>
</dependency>
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>3.0.13.RELEASE</version>
</dependency>
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<!--shiro和thymeleaf集成的扩展依赖,为了能在页面上使用xsln:shiro的标签-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<!-- commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- pinyin4j -->
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>${pinyin4j.version}</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.接口主要代码
客户管理接口代码:
package com.dev.warehouse.bus.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dev.warehouse.bus.entity.Customer;
import com.dev.warehouse.bus.service.ICustomerService;
import com.dev.warehouse.bus.vo.CustomerVo;
import com.dev.warehouse.sys.common.Constast;
import com.dev.warehouse.sys.common.DataGridView;
import com.dev.warehouse.sys.common.ResultObj;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@RestController
@RequestMapping("/customer")
public class CustomerController {
@Autowired
private ICustomerService customerService;
/**
* 查询所有的客户
* @param customerVo
* @return
*/
@RequestMapping("loadAllCustomer")
public DataGridView loadAllCustomer(CustomerVo customerVo){
//1.声明一个分页page对象
IPage<Customer> page = new Page(customerVo.getPage(),customerVo.getLimit());
//2.声明一个queryWrapper
QueryWrapper<Customer> queryWrapper = new QueryWrapper();
queryWrapper.like(StringUtils.isNotBlank(customerVo.getCustomername()),"customername",customerVo.getCustomername());
queryWrapper.like(StringUtils.isNotBlank(customerVo.getConnectionpersion()),"connectionpersion",customerVo.getConnectionpersion());
queryWrapper.like(StringUtils.isNotBlank(customerVo.getPhone()),"phone",customerVo.getPhone());
customerService.page(page,queryWrapper);
return new DataGridView(page.getTotal(),page.getRecords());
}
/**
* 添加一个客户
* @param customerVo
* @return
*/
@RequestMapping("addCustomer")
public ResultObj addCustomer(CustomerVo customerVo){
try {
customerService.save(customerVo);
return ResultObj.ADD_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.ADD_ERROR;
}
}
/**
* 修改一个客户
* @param customerVo
* @return
*/
@RequestMapping("updateCustomer")
public ResultObj updateCustomer(CustomerVo customerVo){
try {
customerService.updateById(customerVo);
return ResultObj.UPDATE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.UPDATE_ERROR;
}
}
/**
* 删除一个客户
* @param id 客户的ID
* @return
*/
@RequestMapping("deleteCustomer")
public ResultObj deleteCustomer(Integer id){
try {
customerService.removeById(id);
return ResultObj.DELETE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.DELETE_ERROR;
}
}
/**
* 批量删除客户
* @param customerVo 选中的客户
* @return
*/
@RequestMapping("batchDeleteCustomer")
public ResultObj batchDeleteCustomer(CustomerVo customerVo){
try {
Collection<Serializable> idList = new ArrayList<Serializable>();
for (Integer id : customerVo.getIds()) {
idList.add(id);
}
customerService.removeByIds(idList);
return ResultObj.DELETE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.DELETE_ERROR;
}
}
/**
* 加载所有客户的下拉列表
* @return
*/
@RequestMapping("loadAllCustomerForSelect")
public DataGridView loadAllCustomerForSelect(){
QueryWrapper<Customer> queryWrapper = new QueryWrapper<Customer>();
queryWrapper.eq("available", Constast.AVAILABLE_TRUE);
List<Customer> list = customerService.list(queryWrapper);
return new DataGridView(list);
}
}
3.前端主要代码
客户前端页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>Right</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link rel="icon" href="/resources/favicon.ico">
<link rel="stylesheet" href="resources/layui/css/layui.css" th:href="@{/resources/layui/css/layui.css}" media="all"/>
<link rel="stylesheet" th:href="@{/resources/css/public.css}" media="all"/>
<link rel="stylesheet" th:href="@{/resources/layui_ext/dtree/dtree.css}" media="all"/>
<link rel="stylesheet" th:href="@{/resources/layui_ext/dtree/font/dtreefont.css}" media="all"/>
</head>
<body>
<!--查询条件-->
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 15px;">
<legend>搜索条件</legend>
</fieldset>
<form action="" method="post" id="searchFrm" lay-filter="searchFrm" class="layui-form">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">客户名称</label>
<div class="layui-input-inline">
<input type="text" name="customername" id="customername" class="layui-input input-radius"
placeholder="请输入客户名称">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">联系人名称</label>
<div class="layui-input-inline">
<input type="text" name="connectionpersion" id="connectionpersion" class="layui-input input-radius" placeholder="请输入联系人名称">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">联系人号码</label>
<div class="layui-input-inline">
<input type="text" name="phone" id="phone" class="layui-input input-radius" placeholder="请输入联系人号码">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block" style="text-align: center;padding-right: 15%;">
<button type="button" class="layui-btn layui-btn-sm layui-btn-radius" lay-submit="" lay-filter="doSearch"><i
class="layui-icon layui-icon-search layui-icon-normal"></i>查询
</button>
<button type="reset" class="layui-btn layui-btn-sm layui-btn-radius layui-btn-warm"><i
class="layui-icon layui-icon-refresh"></i><span>重置</span>
</button>
</div>
</div>
</form>
<!--数据表格-->
<div>
<table class="layui-hide" id="customerTable" lay-filter="customerTable"></table>
<div id="customerToolBar" style="display: none">
<button type="button" lay-event="add" shiro:hasPermission="customer:create" class="layui-btn layui-btn-sm layui-btn-normal layui-btn-radius">
<i class="layui-icon layui-icon-add-1"></i>添加客户
</button>
<button type="button" lay-event="deleteBatch" shiro:hasPermission="customer:create" class="layui-btn layui-btn-sm layui-btn-danger layui-btn-radius">
<i class="layui-icon layui-icon-delete"></i>批量删除
</button>
</div>
<div id="customerRowBar" style="display: none;">
<button type="button" lay-event="update" shiro:hasPermission="customer:update" class="layui-btn layui-btn-sm layui-btn-radius"><i
class="layui-icon layui-icon-edit"></i>编辑
</button>
<button type="button" lay-event="delete" shiro:hasPermission="customer:delete" class="layui-btn layui-btn-sm layui-btn-danger layui-btn-radius"><i
class="layui-icon layui-icon-delete"></i>删除
</button>
</div>
</div>
<!--添加和修改弹出层-->
<div id="addOrUpdateDiv" style="display: none;padding: 10px;padding-right: 5%">
<form action="" method="post" class="layui-form" id="dataFrm" lay-filter="dataFrm">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">客户名称</label>
<div class="layui-input-block">
<input type="hidden" name="id">
<input type="text" name="customername" lay-verify="required" autocomplete="off"
class="layui-input input-radius" placeholder="请输入客户名称">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">客户地址</label>
<div class="layui-input-block">
<input type="text" name="address" lay-verify="required" autocomplete="off" class="layui-input input-radius" placeholder="请输入客户地址">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">客户电话</label>
<div class="layui-input-block">
<input type="text" name="telephone" lay-verify="required" autocomplete="off" class="layui-input input-radius" placeholder="请输入客户电话">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">邮编</label>
<div class="layui-input-block">
<input type="text" name="zip" lay-verify="required" autocomplete="off" class="layui-input input-radius" placeholder="请输入邮编">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">联系人</label>
<div class="layui-input-block">
<input type="text" name="connectionpersion" lay-verify="required" autocomplete="off" class="layui-input input-radius" placeholder="请输入联系人姓名">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">联系电话</label>
<div class="layui-input-block">
<input type="text" name="phone" lay-verify="required|number" autocomplete="off" class="layui-input input-radius" placeholder="请输入联系人电话">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">开户银行</label>
<div class="layui-input-block">
<input type="text" id="bank" name="bank" lay-verify="required" autocomplete="off" class="layui-input input-radius" placeholder="请输入开户银行">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">银行账户</label>
<div class="layui-input-block">
<input type="text" id="account" name="account" lay-verify="required" autocomplete="off" class="layui-input input-radius" placeholder="请输入开户银行">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">email</label>
<div class="layui-input-block">
<input type="text" id="email" name="email" lay-verify="required" autocomplete="off" class="layui-input input-radius" placeholder="请输入email">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">传真</label>
<div class="layui-input-block">
<input type="text" id="fax" name="fax" lay-verify="required" autocomplete="off" class="layui-input input-radius" placeholder="请输入传真">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">是否可用</label>
<div class="layui-input-block">
<input type="radio" name="available" value="1" title="可用" checked="">
<input type="radio" name="available" value="0" title="不可用">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block" style="text-align: center;padding-right: 7%">
<button type="button" class="layui-btn layui-btn-radius" lay-submit="" lay-filter="doSubmit" id="doSubmit"><i
class="layui-icon layui-icon-search layui-icon-normal"></i>提交
</button>
<button type="reset" class="layui-btn layui-btn-radius layui-btn-warm"><i
class="layui-icon layui-icon-refresh"></i><span>重置</span>
</button>
</div>
</div>
</form>
</div>
<script type="text/javascript" src="/resources/layui/layui.js"></script>
<script type="text/javascript">
//提升数据表格的作用域,因为底下还有一个reloadTable方法
var tableIns;
layui.use(['jquery', 'form', 'layer', 'table'], function () {
var $ = layui.jquery;
var form = layui.form;
var layer = layui.layer;
var table = layui.table;
//初始化表格 加载数据
tableIns = table.render({
elem: "#customerTable",
title: "客户数据表格",
url: "/customer/loadAllCustomer",
toolbar: "#customerToolBar",
page: true,
height: "full-180",
cols: [ [
{type:'checkbox',fixed:'left'},
{field: 'id', title: 'ID', align: 'center',width:'50'},
{field: 'customername', title: '客户名称', align: 'center',width:'100'},
{field: 'address', title: '客户地址', align: 'center',width:'150'},
{field: 'telephone', title: '客户电话', align: 'center',width:'140'},
{field: 'zip', title: '邮编', align: 'center',width:'90'},
{field: 'connectionpersion', title: '联系人', align: 'center',width:'130'},
{field: 'phone', title: '联系人电话', align: 'center',width:'130'},
{field: 'bank', title: '开户银行', align: 'center',width:'100'},
{field: 'account', title: '银行账号', align: 'center',width:'160'},
{field: 'email', title: '邮箱', align: 'center',width:'200'},
{field: 'fax', title: '传真', align: 'center',width:'100'},
{field: 'available', title: '是否可用', align: 'center',width:'100',templet:function (d) {
return d.available==1?'<font color="blue">可用</font>':'<font color="red">不可用</font>';
}},
{fixed: 'right', title: '操作', toolbar: '#customerRowBar', align: 'center',width:'180'}
] ],
done: function (data, curr, count) {
//不是第一页时,如果当前返回的数据为0那么就返回上一页
if (data.data.length == 0 && curr != 1) {
tableIns.reload({
page: {
curr: curr - 1
}
})
}
//当是第一页时,如果当前返回的数据为0并且当前为第一页 给一个空的查询条件,并给curr赋初值为1
if (data.data.length==0 && curr==1){
tableIns.reload({
where: "",
page:{
curr:1
}
})
}
}
});
//监控模糊查询按钮事件
form.on("submit(doSearch)", function (data) {
tableIns.reload({
where: data.field,
page: {
curr: 1
}
});
return false;
});
//监控工具条事件
table.on("toolbar(customerTable)", function (obj) {
switch (obj.event) {
case 'add':
openAddLayer();
break;
case 'deleteBatch':
batchDeleteCustomer();
break;
};
});
//监控行工具条事件
table.on("tool(customerTable)", function (obj) {
//获取当前行数据
var data = obj.data;
switch (obj.event) {
case 'delete':
deleteCustomer(data);
break;
case 'update':
updateCustomer(data);
break;
};
});
var mainIndex;
var url;
//打开添加弹出层
function openAddLayer() {
mainIndex = layer.open({
type:1,
content:$("#addOrUpdateDiv"),
area:['700px','500px'],
title:'添加客户',
success:function () {
$("#dataFrm")[0].reset();
url="/customer/addCustomer";
}
});
}
//打开修改的弹出层
function updateCustomer(data) {
mainIndex = layer.open({
type:1,
content:$("#addOrUpdateDiv"),
area:['700px','500px'],
title:'修改客户',
success:function () {
//清空原有的数据
$("#dataFrm")[0].reset();
//装载新的数据
form.val("dataFrm",data);
url="/customer/updateCustomer";
}
});
}
form.on("submit(doSubmit)",function (data) {
$.post(url,data.field,function (res) {
if (res.code==200){
tableIns.reload();
}
layer.msg(res.msg);
layer.close(mainIndex);
});
return false;
});
//删除
function deleteCustomer(data) {
layer.confirm('你确定要删除【' + data.customername + '】这个客户吗?', {icon: 3, title: '提示'}, function (index) {
$.post("/customer/deleteCustomer", {id: data.id},function (res) {
if (res.code == 200) {
tableIns.reload();
}
layer.msg(res.msg);
});
layer.close(index);
});
}
//批量删除
function batchDeleteCustomer() {
//得到选中行
var checkStatus = table.checkStatus('customerTable');
var dataLength = checkStatus.data.length;
if (dataLength>0){
layer.confirm('你确定要删除这些客户数据吗?',{icon: 3,title: '提示'},function (index) {
//获取选中行数据
var data = checkStatus.data;
var ids = "";
$.each(data,function (index, item) {
if (index==0){
ids+="ids="+item.id;
}else {
ids+="&ids="+item.id;
}
});
$.post("/customer/batchDeleteCustomer",ids,function (res) {
if (res.code==200){
//重新刷新表格
tableIns.reload();
}
layer.msg(res.msg);
});
layer.close(index);
});
}else {
layer.msg("请选中操作行")
}
}
});
</script>
</body>
</html>
数据库
总结
涉及代码和配置文件还挺多,还有完整的SQL文件;
需要完整代码的请关注:Java海洋 公众号,发送关键字:源码 即可获得;