基于SSM框架的多商户在线零食商城系统 - 源码深度解析

JavaJavaScriptHTMLCSSSSM框架MavenMySQL
2026-02-079 浏览

文章摘要

本项目是基于SSM(Spring+SpringMVC+MyBatis)框架技术栈构建的多商户在线零食商城系统,旨在为中小型零食品牌、个体经营者及区域代理商提供一个功能完备、运营高效的线上交易与协作平台。其核心业务价值在于解决了传统单商户电商模式在品类扩展、运营灵活性及资源整合方面的局限性。系统通过引...

在当前的电商浪潮中,垂直领域的精细化运营正成为提升竞争力的关键。针对零食这一高频次、多样化的消费品类,传统的单商户电商模式往往受限于品类单一、运营成本高、市场风险集中等问题。为此,我们设计并实现了一个基于SSM(Spring + SpringMVC + MyBatis)技术栈的多角色协作电商平台——"零食云市",旨在为中小型零食品牌商、个体经营者及区域代理商构建一个高效、灵活、可扩展的线上交易生态系统。

该系统通过引入多商户入驻机制,将平台角色清晰地划分为平台管理员、入驻商户和终端消费者,实现了资源的有效整合与职责的明确分离。商户可以专注于商品运营与客户服务,平台方则负责生态治理与流量分配,共同为消费者提供丰富的一站式购物体验。

系统架构与技术栈

"零食云市"采用经典的三层架构设计,严格遵循MVC模式,确保了代码的高内聚、低耦合。

后端技术栈

  • Spring Framework:作为核心控制容器,管理所有Bean的生命周期,通过依赖注入(DI)和面向切面编程(AOP)实现业务组件的解耦。
  • SpringMVC:作为Web层框架,通过DispatcherServlet统一处理HTTP请求路由,结合自定义拦截器实现精细化的权限控制与会话管理。
  • MyBatis:作为持久层框架,通过XML映射文件编写灵活的动态SQL,高效完成复杂的数据操作。
  • Maven:用于项目构建和依赖管理,确保项目结构的标准化和第三方库的版本一致性。

前端技术栈

  • JSP + JSTL:用于服务端页面渲染,结合JSTL标签库简化页面逻辑。
  • jQuery + AJAX:实现前端表单验证、动态数据加载和无刷新交互,提升用户体验。

数据库

  • MySQL 5.7+:作为关系型数据库,存储系统所有业务数据,采用InnoDB引擎保障事务安全。

数据库设计亮点

数据库设计是系统稳定性的基石。"零食云市"的数据库包含22张表,以下重点分析几个核心表的设计亮点。

1. 商品表(product)设计分析

CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `productno` varchar(255) DEFAULT NULL COMMENT '商品编号',
  `productname` varchar(255) DEFAULT NULL COMMENT '商品名称',
  `filename` varchar(255) DEFAULT NULL COMMENT '商品图片',
  `price` decimal(10,2) DEFAULT NULL COMMENT '销售价格',
  `tprice` decimal(10,2) DEFAULT NULL COMMENT '市场价格',
  `fid` varchar(255) DEFAULT NULL COMMENT '一级分类',
  `sid` varchar(255) DEFAULT NULL COMMENT '二级分类',
  `content` text DEFAULT NULL COMMENT '商品描述',
  `delstatus` varchar(255) DEFAULT NULL COMMENT '删除状态',
  `issj` varchar(255) DEFAULT NULL COMMENT '是否上架',
  `istj` varchar(255) DEFAULT NULL COMMENT '是否推荐',
  `saver` varchar(255) DEFAULT NULL COMMENT '操作人',
  `productid` varchar(255) DEFAULT NULL COMMENT '商品ID',
  `leibie` varchar(255) DEFAULT NULL COMMENT '类别',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=139 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='商品表'

设计亮点

  • 价格精度控制:使用decimal(10,2)类型存储价格,精确到分,避免浮点数计算误差。
  • 分类体系设计:通过fid(一级分类)和sid(二级分类)字段实现多级商品分类,支持灵活的商品组织方式。
  • 软删除机制delstatus字段实现软删除,保留历史数据的同时避免物理删除带来的关联问题。
  • 商品状态管理issj(是否上架)和istj(是否推荐)字段实现商品的多维度状态控制。
  • 索引优化建议:在实际生产环境中,建议对productno(商品编号)、fidsid等查询频繁的字段建立索引。

2. 订单主表(ordermsg)设计分析

CREATE TABLE `ordermsg` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `ddno` varchar(255) DEFAULT NULL COMMENT '订单号',
  `memberid` varchar(255) DEFAULT NULL COMMENT '会员ID',
  `productid` varchar(255) DEFAULT NULL COMMENT '商品ID',
  `num` int(11) DEFAULT NULL COMMENT '购买数量',
  `total` double(255,2) DEFAULT NULL COMMENT '订单总额',
  `fkstatus` varchar(255) DEFAULT NULL COMMENT '付款状态',
  `shstatus` varchar(11) DEFAULT NULL COMMENT '收货状态',
  `addr` varchar(255) DEFAULT NULL COMMENT '收货地址',
  `savetime` varchar(255) DEFAULT NULL COMMENT '下单时间',
  `delstatus` varchar(255) DEFAULT NULL COMMENT '删除状态',
  `shfs` varchar(255) DEFAULT NULL COMMENT '配送方式',
  `zffs` varchar(255) DEFAULT NULL COMMENT '支付方式',
  `saver` varchar(255) DEFAULT NULL COMMENT '操作人',
  `isdd` varchar(255) DEFAULT NULL COMMENT '是否订单',
  `fid` varchar(255) DEFAULT NULL COMMENT '父级ID',
  `goodsid` varchar(255) DEFAULT NULL COMMENT '商品ID',
  `goodstype` varchar(255) DEFAULT NULL COMMENT '商品类型',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='订单主表'

设计亮点

  • 订单状态跟踪:通过fkstatus(付款状态)、shstatus(收货状态)等多状态字段,完整记录订单生命周期。
  • 订单号生成策略ddno字段存储唯一订单号,建议采用"时间戳+随机数+商户ID"的生成策略避免重复。
  • 配送与支付方式shfs(配送方式)和zffs(支付方式)字段支持多种业务场景的扩展。
  • 父子订单设计:通过fid(父级ID)和isdd(是否订单)字段支持拆分订单和合并支付等复杂业务逻辑。

订单管理界面

3. 地址表(address)设计分析

CREATE TABLE `address` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` varchar(255) DEFAULT NULL COMMENT '收货人姓名',
  `tel` varchar(255) DEFAULT NULL COMMENT '联系电话',
  `addr` text DEFAULT NULL COMMENT '详细地址',
  `ismr` varchar(255) DEFAULT NULL COMMENT '是否默认地址',
  `delstatus` varchar(255) DEFAULT NULL COMMENT '删除状态',
  `memberid` varchar(255) DEFAULT NULL COMMENT '会员ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='地址表'

设计亮点

  • 默认地址标识ismr字段实现默认地址管理,简化用户下单流程。
  • 软删除支持delstatus字段确保地址数据的历史可追溯性。
  • 用户关联设计memberid字段建立与用户表的关联,支持用户多地址管理。

核心功能实现

1. 多商户商品管理机制

"零食云市"的核心特色在于多商户协作模式。每个入驻商户拥有独立的后台管理系统,可以自主完成商品上架、价格调整、库存管理等操作。

商品上架控制器实现

@Controller
@RequestMapping("/seller")
public class ProductManageController {
    
    @Resource
    private ProductDAO productDAO;
    @Resource
    private CategoryDAO categoryDAO;
    
    @RequestMapping("/productAdd")
    public String productAdd(HttpServletRequest request) {
        // 获取当前登录商户信息
        Seller seller = (Seller) request.getSession().getAttribute("seller");
        List<Category> categoryList = categoryDAO.selectAll();
        request.setAttribute("categoryList", categoryList);
        return "seller/productadd";
    }
    
    @RequestMapping("/productInsert")
    public String productInsert(Product product, HttpServletRequest request) {
        Seller seller = (Seller) request.getSession().getAttribute("seller");
        
        // 生成商品编号:商户ID+时间戳
        String productNo = seller.getId() + "_" + System.currentTimeMillis();
        product.setProductno(productNo);
        product.setSaver(seller.getUsername());
        product.setDelstatus("0");
        product.setIssj("1");
        
        productDAO.add(product);
        return "redirect:productList.do";
    }
    
    @RequestMapping("/productList")
    public String productList(HttpServletRequest request) {
        Seller seller = (Seller) request.getSession().getAttribute("seller");
        String key = request.getParameter("key");
        
        Map<String, Object> map = new HashMap<>();
        map.put("key", key);
        map.put("saver", seller.getUsername());
        
        List<Product> list = productDAO.selectAll(map);
        request.setAttribute("list", list);
        request.setAttribute("key", key);
        return "seller/productlist";
    }
}

商品实体类设计

package com.entity;

import java.math.BigDecimal;

public class Product {
    private int id;
    private String productno;
    private String productname;
    private String filename;
    private BigDecimal price;
    private BigDecimal tprice;
    private String fid;
    private String sid;
    private String content;
    private String delstatus;
    private String issj;
    private String istj;
    private String saver;
    private String productid;
    private String leibie;
    
    // Getter和Setter方法
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    
    public String getProductno() { return productno; }
    public void setProductno(String productno) { this.productno = productno; }
    
    public BigDecimal getPrice() { return price; }
    public void setPrice(BigDecimal price) { this.price = price; }
    
    // 其他Getter/Setter方法...
    
    @Override
    public String toString() {
        return "Product [id=" + id + ", productname=" + productname + 
               ", price=" + price + ", issj=" + issj + "]";
    }
}

商品信息管理

2. 智能购物车与订单处理

系统实现了完整的购物车功能和订单处理流程,支持多商品合并下单、库存校验、价格计算等复杂业务逻辑。

购物车服务实现

@Service
public class CartService {
    
    @Resource
    private ProductDAO productDAO;
    @Resource
    private OrderMsgDAO orderMsgDAO;
    
    /**
     * 添加商品到购物车
     */
    public void addToCart(HttpServletRequest request, String productId, int quantity) {
        HttpSession session = request.getSession();
        Map<String, CartItem> cart = (Map<String, CartItem>) session.getAttribute("cart");
        
        if (cart == null) {
            cart = new HashMap<>();
            session.setAttribute("cart", cart);
        }
        
        Product product = productDAO.findById(Integer.parseInt(productId));
        if (product != null && "1".equals(product.getIssj())) {
            CartItem item = cart.get(productId);
            if (item != null) {
                item.setQuantity(item.getQuantity() + quantity);
            } else {
                item = new CartItem(product, quantity);
                cart.put(productId, item);
            }
        }
    }
    
    /**
     * 生成订单
     */
    public String createOrder(HttpServletRequest request, String addressId, String payType) {
        Member member = (Member) request.getSession().getAttribute("member");
        Map<String, CartItem> cart = (Map<String, CartItem>) request.getSession().getAttribute("cart");
        
        if (cart == null || cart.isEmpty()) {
            return "购物车为空";
        }
        
        // 生成订单号
        String orderNo = generateOrderNo(member.getId());
        double totalAmount = 0.0;
        
        for (CartItem item : cart.values()) {
            OrderMsg order = new OrderMsg();
            order.setDdno(orderNo);
            order.setMemberid(String.valueOf(member.getId()));
            order.setProductid(String.valueOf(item.getProduct().getId()));
            order.setNum(item.getQuantity());
            order.setTotal(item.getProduct().getPrice().doubleValue() * item.getQuantity());
            order.setFkstatus("待付款");
            order.setShstatus("待发货");
            order.setZffs(payType);
            order.setSavetime(new Date().toString());
            
            orderMsgDAO.add(order);
            totalAmount += order.getTotal();
        }
        
        // 清空购物车
        request.getSession().removeAttribute("cart");
        
        return "订单生成成功,总金额:" + totalAmount;
    }
    
    private String generateOrderNo(int memberId) {
        return memberId + "_" + System.currentTimeMillis();
    }
}

提交订单界面

3. 权限管理与会话控制

系统通过自定义拦截器实现精细化的权限控制,确保不同角色只能访问其授权范围内的功能。

权限拦截器实现

@Component
public class AuthInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, Object handler) throws Exception {
        
        String uri = request.getRequestURI();
        HttpSession session = request.getSession();
        
        // 卖家后台权限校验
        if (uri.contains("/seller/")) {
            Seller seller = (Seller) session.getAttribute("seller");
            if (seller == null) {
                response.sendRedirect(request.getContextPath() + "/seller/login.jsp");
                return false;
            }
        }
        
        // 管理员后台权限校验
        if (uri.contains("/admin/")) {
            Admin admin = (Admin) session.getAttribute("admin");
            if (admin == null) {
                response.sendRedirect(request.getContextPath() + "/admin/login.jsp");
                return false;
            }
        }
        
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, 
                          Object handler, ModelAndView modelAndView) throws Exception {
        // 后处理逻辑
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
                               Object handler, Exception ex) throws Exception {
        // 请求完成后的清理工作
    }
}

SpringMVC配置

<!-- springmvc-servlet.xml -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/seller/**"/>
        <mvc:mapping path="/admin/**"/>
        <bean class="com.interceptor.AuthInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

卖家登录界面

4. 数据持久层优化

系统采用MyBatis作为ORM框架,通过动态SQL和结果映射实现高效的数据访问。

商品DAO接口与映射文件

public interface ProductDAO {
    List<Product> selectAll(Map<String, Object> map);
    void add(Product product);
    void update(Product product);
    Product findById(int id);
    void delete(int id);
    List<Product> searchByKeywords(String keywords);
}
<!-- ProductMapper.xml -->
<mapper namespace="com.dao.ProductDAO">

    <select id="selectAll" parameterType="map" resultType="com.entity.Product">
        SELECT * FROM product 
        WHERE delstatus='0'
        <if test="key != null and key != ''">
            AND (productname LIKE CONCAT('%',#{key},'%') 
                 OR productno LIKE CONCAT('%',#{key},'%'))
        </if>
        <if test="saver != null and saver != ''">
            AND saver = #{saver}
        </if>
        ORDER BY id DESC
    </select>

    <insert id="add" parameterType="com.entity.Product">
        INSERT INTO product(
            productno, productname, filename, price, tprice,
            fid, sid, content, delstatus, issj, istj, saver
        ) VALUES(
            #{productno}, #{productname}, #{filename}, #{price}, #{tprice},
            #{fid}, #{sid}, #{content}, '0', #{issj}, #{istj}, #{saver}
        )
    </insert>

    <update id="update" parameterType="com.entity.Product">
        UPDATE product SET
            productname=#{productname}, filename=#{filename}, 
            price=#{price}, tprice=#{tprice}, fid=#{fid}, sid=#{sid},
            content=#{content}, issj=#{issj}, istj=#{istj}
        WHERE id=#{id}
    </update>

</mapper>

5. 前台页面数据渲染

系统使用JSP结合JSTL标签库实现服务端页面渲染,确保数据展示的准确性和一致性。

商品列表页面示例

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
    <title>商品列表 - 零食云市</title>
</head>
<body>
    <div class="product-container">
        <c:forEach items="${productList}" var="product" varStatus="status">
            <div class="product-item">
                <div class="product-image">
                    <img src="${pageContext.request.contextPath}/upload/${product.filename}" 
                         alt="${product.productname}
本文关键词
SSM框架多商户商城零食商城系统源码解析数据库设计

上下篇

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