分享一套锋哥原创的基于Java的微信小程序校园超市(小卖部)系统(SpringBoot4+Vue3)
大家好我是Java1234_小锋老师分享一套锋哥原创的基于Java的微信小程序校园超市(小卖部)系统(SpringBoot4Vue3)项目介绍随着移动互联网和智能手机的普及校园购物方式正在发生深刻变化。传统校园超市(小卖部)存在排队结账时间长、商品信息不透明、库存管理依赖人工、缺乏线上下单渠道等问题难以满足在校师生日益增长的便捷购物需求。微信小程序凭借“无需安装、用完即走”的轻量化特点以及庞大的用户基础成为构建校园电商应用的理想载体。本文以“微信小程序校园超市(小卖部)系统”为研究对象采用前后端分离的架构进行设计与实现。系统整体分为三端面向学生用户的微信小程序端、面向管理员的Web管理后台以及为二者提供统一数据服务的后端接口。后端采用 Spring Boot 4 框架并整合 MyBatis-Plus 持久层框架使用 MySQL 8 作为数据库通过 JWT 实现无状态的登录鉴权管理后台采用 Vue 3 Element Plus ECharts 技术栈构建实现了数据可视化的运营看板用户端基于微信原生小程序开发实现了商品浏览、购物车、下单、评价等完整的购物闭环。系统主要实现了用户注册登录、首页推荐、商品分类浏览、商品详情、购物车管理、订单管理、收货地址管理、商品评价等用户端功能以及数据统计仪表盘、分类管理、商品管理、轮播图管理、订单管理、用户管理、评价管理和公告管理等后台功能。经过功能测试系统运行稳定、界面友好、逻辑正确能够有效提升校园超市的运营效率和学生的购物体验具有一定的实用价值。源码下载链接: https://pan.baidu.com/s/171tKPaZCATWKhNnCPrB4UA?pwd1234提取码: 1234系统展示核心代码package com.java1234.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.java1234.common.PageResult; import com.java1234.common.Result; import com.java1234.entity.Notice; import com.java1234.service.NoticeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.Date; /** * 后台公告管理控制器 */ RestController RequestMapping(/api/admin/notice) public class AdminNoticeController { Autowired private NoticeService noticeService; /** * 分页查询公告 */ GetMapping(/page) public ResultPageResultNotice page( RequestParam(defaultValue 1) Integer pageNum, RequestParam(defaultValue 10) Integer pageSize) { PageNotice page new Page(pageNum, pageSize); LambdaQueryWrapperNotice wrapper new LambdaQueryWrapper(); wrapper.orderByDesc(Notice::getCreateTime); noticeService.page(page, wrapper); return Result.success(new PageResult(page.getTotal(), page.getRecords())); } /** * 新增公告 */ PostMapping public ResultVoid add(RequestBody Notice notice) { notice.setCreateTime(new Date()); noticeService.save(notice); return Result.success(); } /** * 修改公告 */ PutMapping public ResultVoid update(RequestBody Notice notice) { noticeService.updateById(notice); return Result.success(); } /** * 删除公告 */ DeleteMapping(/{id}) public ResultVoid delete(PathVariable Long id) { noticeService.removeById(id); return Result.success(); } }template div classpage-container div classpage-header h2公告管理/h2 el-button typeprimary clickopenDialog()el-iconPlus //el-icon 新增公告/el-button /div el-table :datatableData stripe border stylewidth: 100%; el-table-column propid labelID min-width70 / el-table-column proptitle label标题 min-width200 show-overflow-tooltip / el-table-column propcontent label内容 min-width300 show-overflow-tooltip / el-table-column label状态 min-width80 template #default{ row } el-tag :typerow.status 1 ? success : info{{ row.status 1 ? 发布 : 下架 }}/el-tag /template /el-table-column el-table-column label发布时间 min-width170 template #default{ row }{{ formatDateTime(row.createTime) }}/template /el-table-column el-table-column label操作 min-width160 fixedright template #default{ row } el-button typeprimary link clickopenDialog(row)编辑/el-button el-button typedanger link clickhandleDelete(row.id)删除/el-button /template /el-table-column /el-table el-pagination classpagination v-model:current-pagequery.pageNum v-model:page-sizequery.pageSize :totaltotal layouttotal, sizes, prev, pager, next changeloadData / el-dialog v-modeldialogVisible :titleform.id ? 编辑公告 : 新增公告 width600px el-form :modelform label-width80px el-form-item label标题el-input v-modelform.title //el-form-item el-form-item label内容el-input v-modelform.content typetextarea :rows5 //el-form-item el-form-item label状态 el-switch v-modelform.status :active-value1 :inactive-value0 active-text发布 inactive-text下架 / /el-form-item /el-form template #footer el-button clickdialogVisible false取消/el-button el-button typeprimary clickhandleSave确定/el-button /template /el-dialog /div /template script setup import { ref, reactive, onMounted } from vue import { getNoticePage, addNotice, updateNotice, deleteNotice } from /api/index import { formatDateTime } from /utils/date import { ElMessage, ElMessageBox } from element-plus const tableData ref([]) const total ref(0) const dialogVisible ref(false) const query reactive({ pageNum: 1, pageSize: 10 }) const form reactive({ id: null, title: , content: , status: 1 }) async function loadData() { const res await getNoticePage(query) tableData.value res.data.records total.value res.data.total } function openDialog(row) { if (row) Object.assign(form, row) else Object.assign(form, { id: null, title: , content: , status: 1 }) dialogVisible.value true } async function handleSave() { if (form.id) await updateNotice(form) else await addNotice(form) ElMessage.success(保存成功) dialogVisible.value false loadData() } function handleDelete(id) { ElMessageBox.confirm(确定删除, 提示, { type: warning }).then(async () { await deleteNotice(id) ElMessage.success(删除成功) loadData() }).catch(() {}) } onMounted(() loadData()) /script style scoped .pagination { margin-top: 16px; justify-content: flex-end; } /style!-- 首页 -- view classcontainer !-- 轮播图 -- swiper classbanner-swiper indicator-dots autoplay circular interval4000 swiper-item wx:for{{banners}} wx:keyid image classbanner-img src{{item.image}} modeaspectFill / /swiper-item /swiper !-- 公告 -- view classnotice-bar wx:if{{notices.length 0}} bindtapgoNoticeList text classnotice-icon/text swiper classnotice-swiper vertical autoplay circular interval3000 swiper-item wx:for{{notices}} wx:keyid catchtapgoNoticeDetail data-id{{item.id}} text classnotice-text{{item.title}}/text /swiper-item /swiper text classnotice-arrow›/text /view !-- 分类导航 -- view classcard category-nav view classcategory-item wx:for{{categories}} wx:keyid bindtapgoCategory data-id{{item.id}} view classcategory-icon{{item.name[0]}}/view text classcategory-name{{item.name}}/text /view /view !-- 推荐商品 -- view classsection-title 热销推荐/view view classproduct-grid view classproduct-item card wx:for{{products}} wx:keyid bindtapgoDetail data-id{{item.id}} image classproduct-cover src{{item.cover || /images/default-product.png}} modeaspectFill / view classproduct-info text classproduct-name{{item.name}}/text view classproduct-bottom text classprice price-large¥{{item.price}}/text text classsales已售{{item.sales}}/text /view /view /view /view /view