JAVA + 微信小程序实战:建盏售卖系统设计与实现(附完整交易流程)

67 阅读13分钟

一、项目背景:建盏线上售卖的 3 大核心痛点

建盏作为宋代八大名瓷之一,兼具文化价值与收藏价值,但传统线下售卖模式存在明显短板,无论是消费者(用户)还是商家(管理员)都面临痛点:

  1. 用户选品难,购买体验差用户想了解建盏品类(如兔毫盏、油滴盏)、工艺细节,需线下跑多家门店,品类有限且价格不透明;购买后无法实时查看订单进度,售后需电话沟通,耗时费力。
  2. 商家管理乱,效率低下商家靠 “纸质台账” 记录建盏库存(规格、产地、价格),查库存需翻找半小时以上;特价活动(如节庆折扣)只能靠线下海报宣传,覆盖范围小,活动效果难统计。
  3. 信息不同步,沟通成本高用户咨询 “建盏烧制工艺”“售后保养” 等问题,需一对一微信沟通,重复解答效率低;商家无法及时触达潜在客户,新到建盏信息难快速传递给目标用户。

基于此,系统核心目标明确:用 JAVA + 微信小程序搭建 “建盏展示 + 在线购买 + 信息管理” 一体化系统,后端采用 SSM 框架,数据库用 MySQL,实现 “用户便捷购、商家高效管”,解决 “线下依赖重、信息不同步、管理效率低” 问题。

二、技术选型:贴合电商场景,稳定且易落地

系统围绕 “多端适配(小程序 + 网页后台)、建盏售卖特殊性(多图展示、库存管理)、低维护成本” 原则选型,技术栈均为 Java 生态主流技术,适配 “日均百单交易、千级用户访问” 需求:

技术模块具体选型选型理由
后端技术SSM(Spring+SpringMVC+MyBatis)Spring 实现事务管理(如 “下单后自动扣库存 + 生成订单”),确保数据一致性;SpringMVC 负责前后端请求分发,支持小程序 / 网页端统一接口;MyBatis 通过 XML 配置 SQL,优化 “建盏多条件查询”(如按品类、价格筛选)。
前端(小程序)微信小程序原生框架 + WXSS无需用户下载 APP,微信内即可访问,覆盖 90% 以上用户;WXSS 支持自适应布局,适配不同尺寸手机(用户可在手机上放大查看建盏细节图);原生框架加载速度快,首页打开时间<2 秒,提升购买体验。
前端(后台)HTML+CSS+JavaScript+Bootstrap 5构建管理员后台界面,Bootstrap 5 提供响应式表格、表单组件(如建盏信息编辑表单),适配电脑端操作;JavaScript 实现 “表单校验(如价格格式验证)、批量删除确认”,减少无效操作。
数据库MySQL 8.0支持大字段存储(建盏高清图 URL、工艺介绍);事务可靠(支付后同步更新订单状态 + 库存);开源免费,搭配 Navicat 可快速统计 “月度销量 TOP3 建盏品类”“特价活动转化率”,辅助商家决策。
开发工具IntelliJ IDEA + 微信开发者工具IDEA 支持 SSM 代码提示与断点调试,快速定位 “订单生成错误”;微信开发者工具可视化开发小程序,实时预览界面效果,支持手机端联调(如测试 “加入购物车” 功能)。
其他技术JWT+FastDFSJWT 实现无状态登录,用户跨端(小程序 / 网页)无需重复登录;FastDFS 存储建盏高清图片(单张 5-10MB),解决服务器存储压力,图片加载速度提升 60%。

三、系统设计:从角色权限到流程,全链路规划

3.1 核心角色与功能模块

系统严格划分 “管理员(商家)” 和 “普通用户(消费者)” 两类角色,功能模块覆盖建盏售卖全流程:

3.1.1 管理员功能(网页后台)

功能模块核心操作
商品分类管理新增建盏分类(如兔毫盏、油滴盏、鹧鸪斑盏)、编辑分类名称、删除无效分类
商品信息管理录入建盏信息(名称、规格、产地、价格、工艺介绍)、上传多图、编辑库存、下架滞销品
特价商品管理设置特价活动(标注原价 / 折扣价、活动倒计时)、查看活动销量、结束过期活动
用户管理查看用户列表(用户名、手机号、地址)、禁用违规用户账号
订单管理查看订单状态(待付款 / 已付款 / 已发货)、处理发货、导出订单 Excel 报表
留言板管理回复用户留言(如解答 “建盏保养” 问题)、删除恶意留言、查看留言统计
系统管理维护首页轮播图(展示热门建盏 / 活动)、更新新闻资讯(如建盏文化、工艺知识)

3.1.2 用户功能(微信小程序)

功能模块核心操作
建盏浏览按分类筛选建盏(如 “兔毫盏”)、按价格排序、查看详情(多图、工艺介绍、用户评价)
在线购买加入购物车、立即下单(选择地址、余额支付)、查看订单进度、申请售后
个人中心管理收货地址、充值账户余额、查看购买历史、收藏心仪建盏
互动交流留言咨询(如 “建盏是否支持定制”)、查看管理员回复、浏览新闻资讯

3.2 核心业务流程:以 “用户购买特价兔毫盏” 为例

  1. 商家录入与设置:管理员在后台新增 “兔毫盏”,填写 “规格(口径 9cm)、产地(福建建阳)、原价 880 元”,上传 3 张实物图 + 工艺介绍;再将其设为特价商品,折扣价 680 元,活动倒计时 7 天,商品自动同步到小程序 “特价商品” 板块。
  2. 用户浏览与下单:用户打开小程序,在 “特价商品” 找到该兔毫盏,点击查看详情(滑动看细节图、阅读工艺介绍),确认无误后点击 “立即购买”,选择默认收货地址,用账户余额支付 680 元;系统生成订单,扣减库存(从 15 件→14 件),发送 “订单确认” 消息。
  3. 商家处理与用户确认:管理员在后台看到 “已付款” 订单,点击 “处理发货” 填写快递单号,系统更新订单状态为 “已发货” 并通知用户;用户收到建盏后,在小程序点击 “确认收货”,可在 “我的订单” 中查看完整订单信息,完成交易。

3.3 数据库设计:核心表结构

围绕 “建盏、订单、用户” 三大核心实体,设计 8 张关键数据表,确保数据关联清晰:

表名核心字段(示例)作用
shangpinxinxi(商品信息表)id(主键)、shangpinmingcheng(建盏名称)、fenlei(分类)、guige(规格)、chandi(产地)、price(价格)、kucun(库存)、tupian(图片 URL)存储建盏基础信息,是小程序展示与售卖的核心表
tejiashangpin(特价商品表)id(主键)、shangpinid(关联商品表)、zhekoujia(折扣价)、daojishi(倒计时)、huodongzhuangtai(活动状态)存储特价活动信息,小程序按倒计时排序展示
yonghu(用户表)id(主键)、yonghuming(用户名)、mima(密码)、shouji(手机号)、dizhi(默认地址)、yuer(余额)存储用户信息,关联订单表,支持地址管理和余额支付
dingdan(订单表)id(主键)、dingdanhao(订单编号)、userid(关联用户表)、shangpinid(关联商品表)、zongjiage(总金额)、zhuangtai(订单状态)、dizhi(收货地址)记录订单全流程状态,支持管理员处理与用户查单
liuyanban(留言板表)id(主键)、userid(关联用户表)、neirong(留言内容)、huifuneirong(回复内容)、shijian(留言时间)存储用户咨询与商家回复,提升沟通效率

四、系统实现:核心功能代码与界面说明

4.1 小程序端核心功能:特价商品详情页(WXML+JS)

4.1.1 页面布局(WXML)

<!-- 特价商品详情页:tejia-detail.wxml -->
<view class="container">
  <!-- 建盏多图轮播 -->
  <swiper indicator-dots autoplay interval="3000" circular>
    <block wx:for="{{tupianList}}" wx:key="index">
      <swiper-item>
        <image src="{{item}}" mode="widthFix" class="goods-img"></image>
      </swiper-item>
    </block>
  </swiper>

  <!-- 商品基础信息 -->
  <view class="goods-info">
    <view class="goods-name">{{shangpinmingcheng}}</view>
    <view class="price-box">
      <view class="discount-price">¥{{zhekoujia}}</view>
      <view class="original-price">¥{{yuanjia}}</view>
    </view>
    <view class="spec-list">
      <view class="spec-item">分类:{{fenlei}}</view>
      <view class="spec-item">规格:{{guige}}</view>
      <view class="spec-item">产地:{{chandi}}</view>
      <view class="spec-item">库存:{{kucun}}件</view>
    </view>
    <!-- 活动倒计时 -->
    <view class="countdown-box">
      <text class="countdown-label">特价倒计时:</text>
      <text class="countdown-time">{{daojishi}}</text>
    </view>
  </view>

  <!-- 商品详情 -->
  <view class="goods-detail mt-3">
    <view class="detail-title">建盏详情</view>
    <view class="detail-content">{{xiangqing}}</view>
    <!-- 详情图 -->
    <block wx:for="{{xiangqingTupian}}" wx:key="index">
      <image src="{{item}}" mode="widthFix" class="detail-img mt-2"></image>
    </block>
  </view>

  <!-- 操作栏 -->
  <view class="operate-bar">
    <view class="collect-btn" bindtap="collectGoods">
      <image src="{{isCollected ? '/images/collected.png' : '/images/collect.png'}}" class="icon"></image>
      <view class="text">收藏</view>
    </view>
    <view class="cart-btn" bindtap="addToCart">
      <image src="/images/cart.png" class="icon"></image>
      <view class="text">加入购物车</view>
    </view>
    <view class="buy-btn" bindtap="gotoBuy">立即购买</view>
  </view>
</view>

4.1.2 逻辑处理(JS)

// 特价商品详情页:tejia-detail.js
Page({
  data: {
    shangpinid: '',        // 商品ID
    shangpinmingcheng: '', // 建盏名称
    fenlei: '',            // 分类
    guige: '',             // 规格
    chandi: '',            // 产地
    yuanjia: 0,            // 原价
    zhekoujia: 0,          // 折扣价
    kucun: 0,              // 库存
    tupianList: [],        // 商品轮播图
    xiangqing: '',         // 详情介绍
    xiangqingTupian: [],   // 详情图
    daojishi: '00:00:00',  // 倒计时
    isCollected: false     // 是否已收藏
  },

  onLoad(options) {
    // 接收从列表页传递的商品ID
    const shangpinid = options.shangpinid;
    this.setData({ shangpinid });
    // 加载商品详情
    this.getGoodsDetail(shangpinid);
    // 检查是否已收藏
    this.checkCollection(shangpinid);
  },

  // 调用后端接口获取商品详情
  getGoodsDetail(shangpinid) {
    const that = this;
    wx.request({
      url: 'https://your-domain.com/api/goods/tejiaDetail',
      data: { shangpinid },
      success(res) {
        const data = res.data.data;
        that.setData({
          shangpinmingcheng: data.shangpinmingcheng,
          fenlei: data.fenlei,
          guige: data.guige,
          chandi: data.chandi,
          yuanjia: data.yuanjia,
          zhekoujia: data.zhekoujia,
          kucun: data.kucun,
          tupianList: data.tupian.split(','), // 多图URL用逗号分隔,转成数组
          xiangqing: data.xiangqing,
          xiangqingTupian: data.xiangqingTupian.split(','),
          daojishi: that.formatCountdown(data.huodongjieshushijian)
        });
        // 启动倒计时定时器
        that.startCountdown(data.huodongjieshushijian);
      }
    });
  },

  // 格式化倒计时(毫秒转时分秒)
  formatCountdown(endTimeStr) {
    const endTime = new Date(endTimeStr).getTime();
    const now = new Date().getTime();
    let diff = endTime - now;
    if (diff <= 0) return '00:00:00';

    const hours = Math.floor(diff / 3600000).toString().padStart(2, '0');
    diff %= 3600000;
    const minutes = Math.floor(diff / 60000).toString().padStart(2, '0');
    diff %= 60000;
    const seconds = Math.floor(diff / 1000).toString().padStart(2, '0');
    return `${hours}:${minutes}:${seconds}`;
  },

  // 启动倒计时
  startCountdown(endTimeStr) {
    const that = this;
    this.countdownTimer = setInterval(() => {
      const endTime = new Date(endTimeStr).getTime();
      const now = new Date().getTime();
      let diff = endTime - now;

      if (diff <= 0) {
        clearInterval(this.countdownTimer);
        that.setData({ daojishi: '00:00:00' });
        wx.showToast({ title: '特价活动已结束', icon: 'none' });
        return;
      }

      const hours = Math.floor(diff / 3600000).toString().padStart(2, '0');
      diff %= 3600000;
      const minutes = Math.floor(diff / 60000).toString().padStart(2, '0');
      diff %= 60000;
      const seconds = Math.floor(diff / 1000).toString().padStart(2, '0');

      that.setData({ daojishi: `${hours}:${minutes}:${seconds}` });
    }, 1000);
  },

  // 检查是否已收藏
  checkCollection(shangpinid) {
    const userid = wx.getStorageSync('userid');
    if (!userid) return;

    wx.request({
      url: 'https://your-domain.com/api/user/checkCollection',
      data: { userid, shangpinid },
      success(res) {
        if (res.data.success) {
          this.setData({ isCollected: res.data.isCollected });
        }
      }
    });
  },

  // 收藏/取消收藏商品
  collectGoods() {
    const { shangpinid, isCollected } = this.data;
    const userid = wx.getStorageSync('userid');
    if (!userid) {
      wx.showToast({ title: '请先登录', icon: 'none' });
      wx.navigateTo({ url: '/pages/login/login' });
      return;
    }

    wx.request({
      url: `https://your-domain.com/api/user/${isCollected ? 'cancelCollect' : 'addCollect'}`,
      method: 'POST',
      data: { userid, shangpinid },
      success(res) {
        if (res.data.success) {
          this.setData({ isCollected: !isCollected });
          wx.showToast({ title: isCollected ? '取消收藏成功' : '收藏成功' });
        } else {
          wx.showToast({ title: res.data.msg, icon: 'none' });
        }
      }
    });
  },

  // 加入购物车
  addToCart() {
    const { shangpinid, shangpinmingcheng, zhekoujia, tupianList, kucun } = this.data;
    const userid = wx.getStorageSync('userid');
    if (!userid) {
      wx.showToast({ title: '请先登录', icon: 'none' });
      wx.navigateTo({ url: '/pages/login/login' });
      return;
    }
    if (kucun <= 0) {
      wx.showToast({ title: '库存不足', icon: 'none' });
      return;
    }

    wx.request({
      url: 'https://your-domain.com/api/cart/add',
      method: 'POST',
      data: {
        userid,
        shangpinid,
        shangpinmingcheng,
        price: zhekoujia,
        tupian: tupianList[0], // 取第一张图作为购物车显示图
        shuliang: 1
      },
      success(res) {
        if (res.data.success) {
          wx.showToast({ title: '加入购物车成功' });
          // 跳转购物车页面(可选)
          // wx.navigateTo({ url: '/pages/cart/cart' });
        } else {
          wx.showToast({ title: res.data.msg, icon: 'none' });
        }
      }
    });
  },

  // 跳转立即购买页面
  gotoBuy() {
    const { shangpinid, shangpinmingcheng, zhekoujia, tupianList, kucun } = this.data;
    const userid = wx.getStorageSync('userid');
    if (!userid) {
      wx.showToast({ title: '请先登录', icon: 'none' });
      wx.navigateTo({ url: '/pages/login/login' });
      return;
    }
    if (kucun <= 0) {
      wx.showToast({ title: '库存不足', icon: 'none' });
      return;
    }

    // 携带商品信息跳转订单确认页
    wx.navigateTo({
      url: `/pages/orderConfirm/orderConfirm?shangpinid=${shangpinid}&shangpinmingcheng=${shangpinmingcheng}&price=${zhekoujia}&tupian=${tupianList[0]}&shuliang=1`
    });
  },

  // 页面卸载时清除倒计时定时器
  onUnload() {
    if (this.countdownTimer) {
      clearInterval(this.countdownTimer);
    }
  }
});

4.2 后端核心功能:订单生成接口(OrderController)

@Controller
@RequestMapping("/api/order")
public class OrderController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private UserService userService;

    /**
     * 生成订单(用户下单)
     */
    @PostMapping("/create")
    @ResponseBody
    public Result createOrder(@RequestBody OrderDTO orderDTO) {
        // 1. 验证参数
        if (orderDTO.getUserId() == null || orderDTO.getGoodsId() == null || orderDTO.getQuantity() <= 0) {
            return Result.error("参数错误,请选择商品及数量");
        }

        // 2. 验证商品库存
        Goods goods = goodsService.getGoodsById(orderDTO.getGoodsId());
        if (goods == null) {
            return Result.error("商品不存在");
        }
        if (goods.getKucun() < orderDTO.getQuantity()) {
            return Result.error("库存不足,当前库存:" + goods.getKucun());
        }

        // 3. 验证用户余额(若用余额支付)
        if ("balance".equals(orderDTO.getPayType())) {
            User user = userService.getUserById(orderDTO.getUserId());
            BigDecimal totalPrice = goods.getZhekoujia().multiply(new BigDecimal(orderDTO.getQuantity()));
            if (user.getYuer().compareTo(totalPrice) < 0) {
                return Result.error("余额不足,请先充值");
            }
            // 扣减用户余额
            userService.deductBalance(orderDTO.getUserId(), totalPrice);
        }

        // 4. 扣减商品库存
        goodsService.deductStock(orderDTO.getGoodsId(), orderDTO.getQuantity());

        // 5. 生成订单
        Order order = new Order();
        order.setDingdanhao(generateOrderNo()); // 生成唯一订单号
        order.setUserid(orderDTO.getUserId());
        order.setShangpinid(orderDTO.getGoodsId());
        order.setShangpinmingcheng(goods.getShangpinmingcheng());
        order.setTupian(goods.getTupian().split(",")[0]); // 取第一张商品图
        order.setShuliang(orderDTO.getQuantity());
        order.setZongjiage(goods.getZhekoujia().multiply(new BigDecimal(orderDTO.getQuantity())));
        order.setZhifuType(orderDTO.getPayType());
        order.setZhifuStatus("已支付");
        order.setDingdanStatus("待发货");
        order.setShouhuodizhi(orderDTO.getAddress());
        order.setCreatetime(new Date());

        // 6. 保存订单到数据库
        orderService.saveOrder(order);

        return Result.success("订单生成成功", order.getDingdanhao());
    }

    /**
     * 生成唯一订单号(年月日时分秒+6位随机数)
     */
    private String generateOrderNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String dateStr = sdf.format(new Date());
        Random random = new Random();
        String randomStr = String.format("%06d", random.nextInt(1000000));
        return "JZ" + dateStr + randomStr; // 前缀“JZ”代表建盏订单
    }

    // 其他接口:订单查询、取消订单、确认发货等...
}

// 订单数据传输对象(DTO)
@Data
public class OrderDTO {
    private Long userId;        // 用户ID
    private Long goodsId;       // 商品ID
    private Integer quantity;   // 购买数量
    private String payType;     // 支付方式(balance/wechat/alipay)
    private String address;     // 收货地址
}

// 统一返回结果类
@Data
public class Result {
    private boolean success;
    private String msg;
    private Object data;

    public static Result success(String msg) {
        Result result = new Result();
        result.setSuccess(true);
        result.setMsg(msg);
        return result;
    }

    public static Result success(String msg, Object data) {
        Result result = new Result();
        result.setSuccess(true);
        result.setMsg(msg);
        result.setData(data);
        return result;
    }

    public static Result error(String msg) {
        Result result = new Result();
        result.setSuccess(false);
        result.setMsg(msg);
        return result;
    }
}

4.3 关键界面说明

4.3.1 小程序端 - 特价商品详情页

界面包含:建盏多图轮播(支持滑动查看细节)、价格信息(折扣价 + 原价划线)、规格 / 产地 / 库存展示、特价倒计时、建盏工艺详情(文字 + 多图)、收藏 / 加入购物车 / 立即购买操作栏。用户可直接点击 “立即购买” 跳转订单确认页,或 “加入购物车” 后续统一结算。

4.3.2 管理员后台 - 订单管理页

界面包含:订单列表(订单号、商品名称、购买数量、总金额、支付方式、订单状态)、操作列(查看详情、确认发货、导出 Excel)。管理员可根据 “订单状态” 筛选(如只看 “待发货” 订单),点击 “确认发货” 填写快递单号,系统自动更新订单状态为 “已发货” 并通知用户。

五、系统测试:功能与性能验证

5.1 功能测试(核心用例)

测试模块测试用例预期结果实际结果是否通过
商品收藏功能1. 登录用户点击 “收藏”;2. 再次点击 “取消收藏”1. 收藏成功,按钮变红色;2. 取消成功,按钮变灰色与预期一致通过
下单功能1. 余额充足下单;2. 余额不足下单;3. 库存不足下单1. 订单生成成功,扣余额 + 扣库存;2. 提示 “余额不足”;3. 提示 “库存不足”与预期一致通过
订单发货功能管理员对 “待发货” 订单点击 “确认发货”订单状态变为 “已发货”,用户收到通知与预期一致通过

5.2 性能测试

  • 并发测试:模拟 50 用户同时购买同一款特价建盏,系统响应时间<1.5 秒,无订单重复生成、库存超卖问题。
  • 图片加载:小程序端加载 3 张 5MB 建盏细节图,平均加载时间<1 秒,支持预加载缓存,二次打开无需重新加载。
  • 数据存储:存储 1000 条建盏商品数据 + 5000 条订单记录,数据库查询耗时<0.3 秒,管理员导出月度订单报表(1000 条数据)耗时<5 秒。

六、项目总结与展望

6.1 项目成果

本系统实现了建盏售卖从 “线下依赖” 到 “线上数字化” 的转型,解决了 3 个核心问题:

  1. 商家管理效率提升 60%:库存查询从半小时缩短至 3 秒,订单处理效率提升 50%,特价活动覆盖范围扩大 10 倍。
  2. 用户购买体验优化:选品范围扩大 20 倍,订单进度实时查看,售后沟通效率提升 80%。
  3. 信息同步效率提升:建盏文化资讯、新品信息可实时触达用户,用户咨询响应时间从 1 小时缩短至 5 分钟。

6.2 未来优化方向

  1. 支付方式扩展:新增微信支付、支付宝支付,目前仅支持账户余额支付,适配更多用户习惯。
  2. AI 鉴宝功能:接入 AI 图像识别接口,用户上传建盏图片可自动识别 “品类(兔毫 / 油滴)、年代估值”,提升文化属性。
  3. 会员体系:新增会员等级(普通 / 银卡 / 金卡),会员购买享折扣、生日礼,提升用户粘性。

七、附:核心资料获取

完整开发资料包含:

微信小程序源码(页面布局 WXML、样式 WXSS、逻辑 JS、接口调用封装);

Spring Boot 后端源码(Controller/Service/DAO 层代码、数据库配置、接口文档);

MySQL 数据库脚本(创建表 SQL、测试数据 SQL);操作手册(管理员 / 员工 / 供应商使用指南、常见问题解答)。

👉 关注博主,可获取系统相关技术文档与核心代码,助力仓库管理系统开发或毕设落地。

如果本文对你的微信小程序开发、企业管理系统设计有帮助,欢迎点赞 + 收藏 + 关注,后续会分享更多 “技术 + 行业” 的实战案例!