基于SSM框架的农产品进销存管理平台 - 源码深度解析

JavaJavaScriptMavenHTMLCSSSSM框架MySQL
2026-02-097 浏览

文章摘要

本项目是一款基于SSM(Spring+SpringMVC+MyBatis)框架技术栈构建的农产品进销存管理平台,旨在为中小型农业企业、合作社及个体农户提供一体化的业务数据管理解决方案。其核心业务价值在于解决传统农产品管理中普遍存在的手工记录效率低下、库存数据更新不及时、销售与采购信息脱节等痛点,通过...

在现代农业生产经营中,高效的库存管理是保障农产品流通效率、降低损耗的关键环节。传统的手工记录方式不仅效率低下,还容易导致数据不一致、库存更新不及时等问题。针对这一行业痛点,我们设计并实现了一套面向农产品流通领域的智能仓储管理平台,采用成熟的SSM技术栈构建,为企业提供从入库、出库到库存监控的全流程数字化解决方案。

系统架构与技术栈

该平台采用经典的三层架构设计,前端使用HTML、CSS和JavaScript构建用户界面,后端基于Spring+SpringMVC+MyBatis框架组合。Spring框架作为核心容器,管理业务逻辑层的对象生命周期和事务控制;SpringMVC负责Web请求的接收和响应处理;MyBatis则承担数据持久化职责,通过灵活的SQL映射实现高效的数据操作。

Maven作为项目构建工具,统一管理项目依赖。MySQL数据库存储业务数据,通过合理的表结构设计确保数据的一致性和完整性。整个系统采用模块化设计,各层之间职责分明,便于维护和扩展。

数据库设计亮点分析

物资表(goods)的设计优化

CREATE TABLE `goods` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `goods_name` varchar(200) DEFAULT NULL COMMENT '物品名字 Search111 ',
  `goods_types` int(11) DEFAULT NULL COMMENT '物品种类  Search111 ',
  `goods_number` int(11) DEFAULT NULL COMMENT '物资数量  Search111 ',
  `goods_photo` varchar(200) DEFAULT NULL COMMENT '物品照片',
  `danwei` varchar(200) DEFAULT NULL COMMENT '计量单位',
  `goods_content` varchar(200) DEFAULT NULL COMMENT '物品详情',
  `flag` int(11) DEFAULT NULL COMMENT '删除标志',
  `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='物资'

该表设计体现了几个重要考量:首先使用flag字段实现逻辑删除,避免物理删除导致的数据丢失风险;goods_types字段通过字典表关联,实现物品种类的统一管理;goods_number字段实时记录库存数量,为库存预警提供数据基础。字符字段长度统一设置为200,既满足业务需求又避免过度分配存储空间。

出入库订单表(in_out_order)的业务逻辑设计

CREATE TABLE `in_out_order` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `order_name` varchar(200) DEFAULT NULL COMMENT '订单名  Search111 ',
  `caozuo_name` varchar(200) DEFAULT NULL COMMENT '操作人姓名  Search111 ',
  `caozuo_table` varchar(200) DEFAULT NULL COMMENT '操作人表名',
  `order_types` int(11) DEFAULT NULL COMMENT '类型  Search111 ',
  `insert_time` timestamp NULL DEFAULT NULL COMMENT '出入库时间  Search111 ',
  `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='出入库订单'

该表通过order_types字段区分入库和出库操作,caozuo_namecaozuo_table记录了操作人信息,实现操作轨迹的完整追溯。时间戳字段的设计支持按时间范围查询,为统计分析提供便利。

字典表(dictionary)的系统扩展性设计

CREATE TABLE `dictionary` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `dic_code` varchar(200) DEFAULT NULL COMMENT '字典代码',
  `dic_name` varchar(200) DEFAULT NULL COMMENT '字典名称',
  `code_index` int(11) DEFAULT NULL COMMENT '编码索引',
  `index_name` varchar(200) DEFAULT NULL COMMENT '索引名称',
  `super_id` int(11) DEFAULT NULL COMMENT '父级ID',
  `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='字典表'

字典表采用树形结构设计,通过super_id字段实现多级字典分类,支持系统的灵活扩展。这种设计使得新增业务类型时无需修改表结构,只需在字典表中添加相应记录即可。

核心功能实现

物资管理模块

物资管理是系统的核心功能之一,实现了农产品的全生命周期管理。管理员可以通过界面完成物资的添加、修改、查询和删除操作。

物资管理界面

对应的实体类设计体现了业务对象的完整属性:

@Entity
@Table(name = "goods")
public class Goods implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    
    @Column(name = "goods_name")
    private String goodsName;
    
    @Column(name = "goods_types")
    private Integer goodsTypes;
    
    @Column(name = "goods_number")
    private Integer goodsNumber;
    
    @Column(name = "goods_photo")
    private String goodsPhoto;
    
    private String danwei;
    
    @Column(name = "goods_content")
    private String goodsContent;
    
    private Integer flag;
    
    @Column(name = "create_time")
    private Timestamp createTime;
    
    // getter和setter方法
    public Integer getId() {
        return id;
    }
    
    public void setId(Integer id) {
        this.id = id;
    }
    
    public String getGoodsName() {
        return goodsName;
    }
    
    public void setGoodsName(String goodsName) {
        this.goodsName = goodsName;
    }
    
    // 其他getter和setter方法...
}

服务层代码实现了复杂的业务逻辑,包括库存校验、数量更新等:

@Service
public class GoodsService {
    
    @Autowired
    private GoodsMapper goodsMapper;
    
    /**
     * 更新物资数量
     */
    @Transactional
    public void updateGoodsNumber(Integer goodsId, Integer changeNumber, Integer operationType) {
        Goods goods = goodsMapper.selectById(goodsId);
        if (goods == null) {
            throw new BusinessException("物资不存在");
        }
        
        Integer currentNumber = goods.getGoodsNumber();
        Integer newNumber = currentNumber;
        
        if (operationType == 1) { // 入库
            newNumber = currentNumber + changeNumber;
        } else if (operationType == 2) { // 出库
            if (currentNumber < changeNumber) {
                throw new BusinessException("库存不足");
            }
            newNumber = currentNumber - changeNumber;
        }
        
        goods.setGoodsNumber(newNumber);
        goodsMapper.updateById(goods);
        
        // 记录操作日志
        recordOperationLog(goodsId, changeNumber, operationType);
    }
    
    private void recordOperationLog(Integer goodsId, Integer changeNumber, Integer operationType) {
        // 记录详细的操作日志
    }
}

出入库订单管理

出入库订单管理实现了农产品流通的精确追踪,每个操作都生成完整的订单记录。

出入库订单管理

控制器层处理前端请求,确保数据的完整性和一致性:

@RestController
@RequestMapping("/inOutOrder")
public class InOutOrderController {
    
    @Autowired
    private InOutOrderService inOutOrderService;
    
    @PostMapping("/create")
    public R createOrder(@RequestBody InOutOrder order, HttpServletRequest request) {
        try {
            // 设置操作人信息
            String operator = getCurrentUser(request);
            order.setCaozuoName(operator);
            order.setCaozuoTable("yonghu");
            order.setCreateTime(new Timestamp(System.currentTimeMillis()));
            
            inOutOrderService.createOrder(order);
            return R.ok().put("data", order);
        } catch (Exception e) {
            return R.error("创建订单失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/list")
    public R getOrderList(@RequestParam Map<String, Object> params) {
        PageUtils page = inOutOrderService.queryPage(params);
        return R.ok().put("data", page);
    }
    
    private String getCurrentUser(HttpServletRequest request) {
        // 从session或token中获取当前用户信息
        return "admin"; // 示例代码
    }
}

MyBatis的Mapper接口定义了数据操作的具体方法:

@Mapper
public interface InOutOrderMapper extends BaseMapper<InOutOrder> {
    
    /**
     * 自定义查询方法
     */
    List<InOutOrder> selectByConditions(@Param("orderName") String orderName,
                                      @Param("startTime") Date startTime,
                                      @Param("endTime") Date endTime,
                                      @Param("orderTypes") Integer orderTypes);
    
    /**
     * 分页查询
     */
    List<InOutOrder> selectPageWithCustom(Map<String, Object> params);
}

对应的XML映射文件编写了灵活的SQL查询:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mapper.InOutOrderMapper">

    <select id="selectByConditions" resultType="com.entity.InOutOrder">
        SELECT * FROM in_out_order 
        WHERE 1=1
        <if test="orderName != null and orderName != ''">
            AND order_name LIKE CONCAT('%', #{orderName}, '%')
        </if>
        <if test="startTime != null">
            AND insert_time >= #{startTime}
        </if>
        <if test="endTime != null">
            AND insert_time &lt;= #{endTime}
        </if>
        <if test="orderTypes != null">
            AND order_types = #{orderTypes}
        </if>
        ORDER BY create_time DESC
    </select>

</mapper>

委托出入库管理

委托出入库功能允许用户提交委托申请,管理员审核后执行实际操作,实现了权限分离和业务流程的规范化。

委托出入库管理

委托订单实体类扩展了基础订单功能:

@Entity
@Table(name = "entrust_in_out_order")
public class EntrustInOutOrder extends BaseEntity {
    
    @Column(name = "yonghu_id")
    private Integer yonghuId;
    
    @Column(name = "order_name")
    private String orderName;
    
    @Column(name = "order_types")
    private Integer orderTypes;
    
    @Column(name = "insert_time")
    private Timestamp insertTime;
    
    @Column(name = "caozuo_name")
    private String caozuoName;
    
    @Column(name = "caozuo_table")
    private String caozuoTable;
    
    @Column(name = "caozuo_types")
    private Integer caozuoTypes;
    
    @Column(name = "update_time")
    private Timestamp updateTime;
    
    // 关联用户信息
    @Transient
    private String yonghuName;
    
    @Transient
    private String phone;
    
    // getter和setter方法
}

用户管理与权限控制

系统支持多角色用户管理,不同角色具有不同的操作权限。

用户管理

用户表设计包含了完整的个人信息字段:

CREATE TABLE `yonghu` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(200) DEFAULT NULL COMMENT '用户名',
  `password` varchar(200) DEFAULT NULL COMMENT '密码',
  `name` varchar(200) DEFAULT NULL COMMENT '姓名  Search111 ',
  `phone` varchar(200) DEFAULT NULL COMMENT '手机号 Search111 ',
  `id_number` varchar(200) DEFAULT NULL COMMENT '身份证号  Search111 ',
  `sex_types` int(11) DEFAULT NULL COMMENT '性别',
  `my_photo` varchar(200) DEFAULT NULL COMMENT '个人照片',
  `nation` varchar(200) DEFAULT NULL COMMENT '民族',
  `politics_types` int(11) DEFAULT NULL COMMENT '政治面貌',
  `birthplace` varchar(200) DEFAULT NULL COMMENT '籍贯',
  `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='用户'

Spring Security配置实现了基于角色的访问控制:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Autowired
    private UserDetailsService userDetailsService;
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
            .logout()
            .permitAll();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder());
    }
}

实体模型设计

系统采用领域驱动设计思想,实体类严格对应数据库表结构。基础实体类封装了通用属性:

public abstract class BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private Long id;
    private Timestamp createTime;
    private Timestamp updateTime;
    
    // 通用方法
    public boolean isNew() {
        return this.id == null;
    }
    
    // getter和setter方法
    public Long getId() {
        return id;
    }
    
    public void setId(Long id) {
        this.id = id;
    }
    
    public Timestamp getCreateTime() {
        return createTime;
    }
    
    public void setCreateTime(Timestamp createTime) {
        this.createTime = createTime;
    }
    
    public Timestamp getUpdateTime() {
        return updateTime;
    }
    
    public void setUpdateTime(Timestamp updateTime) {
        this.updateTime = updateTime;
    }
}

配置实体类展示了系统配置项的管理方式:

@TableName("config")
public class ConfigEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @TableId(type = IdType.AUTO)
    private Long id;
    
    /**
     * key
     */
    private String name;
    
    /**
     * value
     */
    private String value;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

功能展望与优化方向

1. 引入Redis缓存提升性能

当前系统在高并发场景下可能存在性能瓶颈。引入Redis作为缓存层,可以显著提升系统响应速度。

@Service
public class GoodsCacheService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private GoodsMapper goodsMapper;
    
    private static final String GOODS_KEY_PREFIX = "goods:";
    private static final long EXPIRATION_TIME = 3600; // 1小时
    
    public Goods getGoodsById(Integer id) {
        String key = GOODS_KEY_PREFIX + id;
        Goods goods = (Goods) redisTemplate.opsForValue().get(key);
        
        if (goods == null) {
            goods = goodsMapper.selectById(id);
            if (goods != null) {
                redisTemplate.opsForValue().set(key, goods, EXPIRATION_TIME, TimeUnit.SECONDS);
            }
        }
        
        return goods;
    }
    
    public void evictGoodsCache(Integer id) {
        String key = GOODS_KEY_PREFIX + id;
        redisTemplate.delete(key);
    }
}

2. 消息队列实现异步处理

对于库存同步、报表生成等耗时操作,可以引入消息队列实现异步处理,提升用户体验。

@Component
public class InventoryMessageProducer {
    
    @Autowired
    private AmqpTemplate rabbitTemplate;
    
    public void sendInventoryUpdateMessage(InventoryUpdateMessage message) {
        rabbitTemplate.convertAndSend("inventory.exchange", "inventory.update", message);
    }
}

@Component
public class InventoryMessageConsumer {
    
    @Autowired
    private InventoryService inventoryService;
    
    @RabbitListener(queues = "inventory.update.queue")
    public void processInventoryUpdate(InventoryUpdateMessage message) {
        inventoryService.asyncUpdateInventory(message);
    }
}

3. 微服务架构改造

随着业务复杂度增加,可以将单体应用拆分为微服务架构,提高系统的可维护性和扩展性。

# application.yml
spring:
  application:
    name: inventory-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080

server:
  port: 8081

# 库存服务配置
inventory:
  update:
    batch-size: 100
    timeout: 5000

4. 移动端适配与PWA技术

开发移动端应用,支持PWA(渐进式Web应用)技术,提供接近原生应用的体验。

// service-worker.js
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open('inventory-v1').then((
本文关键词
SSM框架农产品进销存管理库存管理源码解析

上下篇

上一篇
没有更多文章
下一篇
没有更多文章