# 仓库管理系统 **Repository Path**: tj_vip/warehouse-management-system ## Basic Information - **Project Name**: 仓库管理系统 - **Description**: 这是一个开源的前后端分离的仓储管理系统 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 0 - **Created**: 2023-04-25 - **Last Updated**: 2025-04-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 《恒合仓库》开发实施步骤文档 1. 项目初始框架简介 《恒合仓库》项目为前后端分离项目,在init目录下有两个文件夹分别为后端项目warehouse_management和前端项目warehouse_boot_pc,这两个目录作为初始项目架构,在此基础上进行开发。 服务端应用采用Java企业级框架,使用了Spring Boot、MyBatis和redis等组件和技术; 前端应用采用SPA架构,使用了Vue CLI4、Axios、Element-plus、Apache Echarts5等组件和技术; 2. 服务端应用初始搭建 2.1 建立数据库 在1. 数据库设计及初始化脚本目录下,有sql脚本文件:warehouse.sql ,在mysql环境下执行这两个脚本,应用的数据库即建立。 # 登录mysql,回车输入登录密码 mysql -uroot -p # 在mysql中执行以下命令,导入sql数据 mysql> source warehouse.sql文件路径 2.2 安装启动redis 使用redis默认端口6379,如果不是默认端口,需要在配置文件进行配置,这里使用默认端口即可。 2.3 应用导入 在集成开发工具IDE(如:IDEA)中,导入项目init\warehouse_management,如下图: 配置maven环境,刷新pom.xml文件,下载依赖 在application.yml中修改数据库连接配置,示例如下: 2.4 启动后台应用 启动类src/main/java/com/wk/warehouse/WarehouseManagementApplication中执行main方法,启动后台项目 2.5 应用测试 - 获取验证码 - 登录 3. 前端应用初始搭建 3.1 开发环境准备 请安装以下开发工具(未详述的可在网上找相关资料) - 安装VS Code(已经安装过的,此步骤省略) - 安装前端开发环境Node.js 下载地址:http://nodejs.cn/download/current/ - 以管理员身份进入命令窗口 - 为npm配置国内镜像 在命令窗口执行命令:npm config set registry https://registry.npm.taobao.org/ - 命令执行完毕后,可用如下命令检测 npm config get registry - 安装yarn 在命令窗口执行命令:npm install -g yarn - 为yarn配置国内镜像 在命令窗口执行命令:yarn config set registry https://registry.npm.taobao.org/ - 命令执行完毕后,可用如下命令检测 yarn config get registry 3.2 安装应用依赖 在命令窗口,进入PC前端应用根目录warehouse_boot_pc下,执行命令:yarn,安装依赖。 # 切换到前端根目录 cd D:/warehouse_boot_pc # 安装项目依赖 yarn 3.3 通过IDE打开编辑前端应用 使用VS Code打开目录warehouse_boot_pc,进入终端命令窗口,切换到项目根路径,执行yarn dev启动前端项目。 如下图,配置服务器地址: .env文件中定义变量 3.4 应用启动和测试 在命令窗口,进入前端应用根目录warehouse_boot_pc下,执行命令:npm run dev 启动应用。 录入账号:admin,密码:123456,验证码,登录系统 4. 开发示例:角色列表 4.1 服务端 - entity包中添加实体类:Role package com.wk.warehouse.entity; import com.fasterxml.jackson.annotation.JsonFormat; import java.util.Date; public class Role { private int roleId; private String roleName; private String roleDesc; private String roleCode; private String roleState; private int createBy; @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date createTime; private int updateBy; private Date updateTime; private String getCode; public int getRoleId() { return roleId; } public void setRoleId(int roleId) { this.roleId = roleId; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } public String getRoleDesc() { return roleDesc; } public void setRoleDesc(String roleDesc) { this.roleDesc = roleDesc; } public String getRoleCode() { return roleCode; } public void setRoleCode(String roleCode) { this.roleCode = roleCode; } public String getRoleState() { return roleState; } public void setRoleState(String roleState) { this.roleState = roleState; } public int getCreateBy() { return createBy; } public void setCreateBy(int createBy) { this.createBy = createBy; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public int getUpdateBy() { return updateBy; } public void setUpdateBy(int updateBy) { this.updateBy = updateBy; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } public String getGetCode() { return getCode; } public void setGetCode(String getCode) { this.getCode = getCode; } @Override public String toString() { return "Role{" + "roleId=" + roleId + ", roleName='" + roleName + '\'' + ", roleDesc='" + roleDesc + '\'' + ", roleCode='" + roleCode + '\'' + ", roleState='" + roleState + '\'' + ", createBy=" + createBy + ", createTime=" + createTime + ", updateBy=" + updateBy + ", updateTime=" + updateTime + '}'; } } - mapper包中添加接口:RoleMapper package com.wk.warehouse.mapper; import com.wk.warehouse.entity.Role; import java.util.List; public interface RoleMapper { /** * 分页模糊查询角色 */ public List selectRoles(HashMap map); } - resources目录下,创建mapper文件夹,添加映射文件:RoleMapper.xml - service包中添加RoleService接口 import com.wk.warehouse.entity.Role; import java.util.HashMap; import java.util.List; import javax.servlet.http.HttpServletRequest; public interface RoleService { /** * 查询角色 */ public List selectRoles(HashMap map); /** * 查询角色总条数 */ public int roleCount(HashMap map); } - service/impl包中添加RoleServiceImpl package com.wk.warehouse.service.impl; import java.util.HashMap; import java.util.List; import com.wk.warehouse.entity.Role; import com.wk.warehouse.mapper.RoleMapper; import com.wk.warehouse.service.RoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class RoleServiceImp implements RoleService { @Autowired private RoleMapper roleMapper; /** * 分页模糊查询角色 */ @Override public List selectRoles(HashMap map) { return roleMapper.selectRoles(map); } /** * 查询总条数 */ @Override public int roleCount(HashMap map) { return roleMapper.roleCount(map); } } - controller包中添加RoleController package com.wk.warehouse.controller; import java.util.HashMap; import java.util.List; import com.wk.warehouse.entity.Result; import com.wk.warehouse.entity.Role; import com.wk.warehouse.service.RoleService; import com.wk.warehouse.page.Page; import com.wk.warehouse.util.CurrentUser; import com.wk.warehouse.util.TokenUtils; import com.wk.warehouse.util.WarehouseConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/role") public class RoleController { @Autowired private RoleService roleService; /** * 分页模糊查询角色 */ @GetMapping("/role-page-list") public Result rolePageList(Page page, Role role) { HashMap map = new HashMap(); map.put("role", role); // 获取总条数 int totalNum = roleService.roleCount(map); page.setTotalNum(totalNum); map.put("page", page); // 查询所有用户 List roleList = roleService.selectRoles(map); page.setResultList(roleList); return Result.ok(page); } } 4.2 前端 - 创建文件src/views/role/index.vue - 配置路由 4.3 测试 5. 《恒合仓库》需求说明 5.1 系统目标 为满足日益扩大的仓库管理需求,对仓库中商品进销存进行统一管理,而开发此系统。本系统主要包含: 1、用户管理(查询用户、添加用户、修改用户、删除用户、导出数据、批量删除、禁用/启用用户、重置密码、分配角色、更改权限) 2、角色管理(查询角色、添加角色、修改角色、删除角色、导出数据、禁用/启用角色、更改权限) 3、权限管理(查询权限、添加权限、修改权限、删除角色、禁用/启用权限) 4、 商品管理(查询商品、添加商品、修改商品、商品审核等) 5、 商品分类管理(商品分类的添加、商品分类的查询、商品分类的修改、商品分类的删除等) 6、 采购管理(我的采购单、添加采购单、采购单的审核等) 7、 入库管理(入库单、保存入库单、确认入库等) 8、出库管理(出库单、保存出库单、审核出库单等) 9、统计管理(各个仓库库存信息、仓库占有比、仓库存储走势、出入库信息统计、采购量占比、实时数据监测) 10、调货管理(调货单查询、确认调货) 11、仓库管理(查询仓库、添加仓库、修改仓库、删除仓库、导出数据) 12、供货商管理(供货商添加、供货商修改、供货商的查询等) 13、品牌管理(品牌添加、品牌修改、品牌的查询等) 14、产地管理(产地添加、产地修改、产地的查询等) 15、站内信管理(我的站内信、未读消息、站内信发送、站内信查询等) 5.2 模块结构 5.3 模块功能描述 5.3.1 用户管理 - 用户登录 输入:用户名、密码、验证码 根据用户名、密码、验证码进行登录,所有参数页面必须进行非空验证和格式验证; 输出:登录成功,将token存储本地 - 查询用户 输入:分页模糊查询用户 输出:分页查询结果 - 添加用户 - 修改用户 输入:用户名(不能修改)、昵称。 输出:返回添加是否成功,成功返回用户列表。 - 删除用户 根据用户id删除该用户,删除前给用户提示,是否确认删除。 - 导出数据 将所有模糊查询数据导出到excel中 - 禁用/启用用户 修改用户的状态,0为禁用,字体为红色,不显示重置密码、分配角色、更改权限等功能,1为启用,显示重置密码、分配角色、更改权限等功能。 - 重置密码 将用户的密码重置为某个初始值,比如123456。 - 分配角色 - 更改权限 5.3.2 角色管理 - 查询角色 - 添加角色 - 导出数据 导出所有角色的模糊查询结果到excel文件中 - 修改角色 - 删除角色 根据角色id删除某角色,删除前给用户做出提示 - 禁用/启用角色 修改角色状态,0为禁用,字体显示为红色,不显示更改权限按钮,1为启用,显示更改权限按钮。 - 更改权限 5.3.3 权限管理 - 查询权限 - 添加权限 输入:权限名称、权限描述、权限类型、权限code、权限url,获取权限父id、添加人、添加时间、修改人、修改时间 注意: 1、没有选中任何权限,添加一级权限(模块) ,显示权限名称、权限描述,权限类型只能选择模块,禁用列表和按钮。 2、选中一级权限,添加二级权限(列表) ,显示权限名称,权限描述、权限url,权限类型只能选择列表,禁用模块和按钮 3、选中二级权限,添加三级权限(按钮) ,显示权限名称,权限描述、权限url、权限code,权限类型只能选择按钮,禁用模块和列表 4、选中三级权限,给用户提示当前权限不能添加子权限。 5、权限名称、权限url、权限code都要做唯一验证 输出:返回添加是否成功,成功返回权限树页面。 - 修改权限 整个权限列表只能是单选,如果用户没有选中权限,提示用户选择,用户选择了某权限时,进行修改。 - 启用/禁用权限 修改权限的状态,0为禁用,禁用时页面进行置灰处理,如果禁用权限会自动禁用该权限及其所有子权限,1为启用,启用权限会启用该权限及其所有子权限。 - 删除权限 删除权限会关联删除该权限及其所有子权限 5.3.4 商品管理 - 查询商品 - 添加商品 当添加一条商品后,默认的是未上架的商品,且未上架的商品不能出库,已上架的商品不能修改 - 修改商品 5.3.5 商品分类 - 查询商品分类 - 添加分类 1、未选中分类,则添加一级分类 2、选中一级分类,则添加该一级分类下的二级分类 3、选中二级分类,给用户提示,该分类已是最小分类,不能添加子分类 - 修改分类 - 删除分类 删除分类会删除该分类及其所有子分类 5.3.6 采购管理 - 查询采购列表 - 添加采购单 在商品列表页面,点击采购跳转到添加采购单的页面,在页面显示商品名称、仓库名称、供货商名称、产地名称,填写预计采购数量、采购人姓名、采购人电话等。 - 修改采购单 只有当实际采购量为空的情况下才能够对采购单进行修改 - 生成入库单 采购单实际采购数量必须大于0,没有实际采购数量不能生成入库单 添加一条入库单信息,修改当前采购单的状态为已入库 5.3.7 入库管理 - 入库单查询 - 确定入库 修改库存数量、修改入库状态 5.3.8 出库管理 - 添加出库单 用户在商品列表单击出库,填写出库数量,即可出库,此时该出库单处于未审核状态 - 出库单查询 - 确定出库 出库单数量必须小于等于库存,更新库存,修改出库状态为1 5.3.9 统计管理 5.3.10 调货管理 调货业务详细说明: 当某种商品库存不足,又急需上架时,我们可以选择从另一个仓库调货。如:我们在商品列表选择仓库(假设为A仓库),会展示该仓库所属的商品信息,如果某种商品面临缺货,我们可以点击当前页面的调货按钮进行调货,即给该商品所在的仓库(假设仓库名称为A仓库)调货。 当点击商品列表的调货按钮后会跳转到新的页面,这个页面是源仓库(假设仓库名称为B仓库)商品信息,我们选择源仓库(B仓库),会自动展示该仓库所属商品信息。我们在B仓库找到需要调往A仓库的商品并点击对应的调货按钮(即从B仓库调往A仓库)会弹出一个弹出框,修改商品编号、输入正确的调货数量后,点击调货会向调货列表新增一条数据,该数据调货状态初始为未完成状态。当我们线下调货完成后,我们在调货列表完成调货。完成调货以后,会向入库单新增一条默认已审核的入库信息,至此,调货流程完毕。 调货功能流程: 1、商品列表点击调货按钮 2、点击调货按钮后,会跳转至一个新的页面。在本页面需要选择源仓库(即从哪个仓库调货),找到需要调货的商品,点击调货跳出弹出框。 3、修改弹出框调货信息并点击调货 点击调货按钮,进行逻辑判断: ① 修改商品编号,并做唯一校验 ② 调货数量,不能大于库存 ③ 源仓库和目标仓库不能相同(不能再同一个仓库内进行调货) 满足以上条件后: ① 向商品表插入一条数据(源商品id查出商品信息,然后插入,此时商品编号,库存为空,id自增) ② 修改目标商品的仓库id和商品编号 ③ 向调货单表插入一条数据,调货状态为0,未审核 4、查询调货单 5、 确认调货 - 修改调货状态为已完成 - 修改源商品库存 - 修改目标商品库存 - 向入库单插入一条数据,默认已审核 5.3.11 仓库管理 - 查询仓库 - 添加仓库 - 修改仓库