大家好,我是Java1234_小锋老师,分享一套锋哥原创的微信小程序鲜花商城(花店)管理系统(SpringBoot4+Vue3)。

项目介绍
鲜花消费已经从节日礼品扩展到日常问候、探望慰问和商务庆贺。许多花店仍然依靠电话记单和手工改库存,订单状态不容易追踪,会员也难以随时查看在售花束。微信小程序不用单独安装,适合作为花店面向顾客的入口;管理端则需要在浏览器中完成商品、订单和会员维护。基于这一需求,本文设计并实现了微信小程序鲜花商城(花店)管理系统。
系统采用前后端分离。服务端使用 Java 17 与 Spring Boot 4.1 提供 REST 接口,持久层使用 MyBatis-Plus 访问 MySQL 8 数据库 db_flower_shop。顾客端为微信小程序,支持注册登录、分类检索、购物车、下单支付、收货评价和个人中心。管理端使用 Vue 3、Vite、Element Plus、Pinia 和 ECharts,提供数据统计、商品运营、订单发货、评价回复、公告发布以及右上角个人中心。身份认证使用 JWT,日期按 2026-09-28 的格式输出,日期时间按 2026-09-28 17:25:17 的格式输出。
论文依次完成了需求分析、总体设计、数据库设计和功能实现。概念结构给出了十二个实体的属性图,并按交易、商品运营两条线索绘制实体联系图。逻辑结构列出了每张数据表的字段名、类型、长度、是否为空和备注。系统实现部分结合登录、加购、下单和发货时序图说明了核心代码。测试表明,会员购物流程与管理员履约流程能够闭环运行,达到了本科毕业设计的预期目标。
源码下载
链接: https://pan.baidu.com/s/1fQ5hiMqq5K7bmCAY1vPRyA?pwd=1234 提取码: 1234
系统展示
核心代码
package com.java1234.controller.admin;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.java1234.common.BizException;
import com.java1234.common.Result;
import com.java1234.entity.User;
import com.java1234.service.UserService;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 会员管理接口
*/
@RestController
@RequestMapping("/api/admin/user")
public class UserController {
private final UserService userService;
/**
* 注入会员业务
*/
public UserController(UserService userService) {
this.userService = userService;
}
/**
* 分页查询会员
*/
@GetMapping("/page")
public Result<Page<User>> page(@RequestParam(defaultValue = "1") long pageNum,
@RequestParam(defaultValue = "10") long pageSize,
String username, Integer status) {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StringUtils.hasText(username), User::getUsername, username);
wrapper.eq(status != null, User::getStatus, status);
wrapper.orderByDesc(User::getId);
Page<User> page = userService.page(new Page<>(pageNum, pageSize), wrapper);
page.getRecords().forEach(user -> user.setPassword(null));
return Result.success(page);
}
/**
* 启用或禁用会员
*/
@PutMapping("/status")
public Result<Void> status(@RequestParam Long id, @RequestParam Integer status) {
if (status == null || (status != 0 && status != 1)) {
throw new BizException("状态不正确");
}
User user = userService.getById(id);
if (user == null) {
throw new BizException("会员不存在");
}
user.setPassword(null);
user.setStatus(status);
userService.updateById(user);
return Result.success();
}
}
<template>
<div class="page-card">
<div class="toolbar">
<el-input v-model="query.name" placeholder="鲜花名称" clearable style="width: 200px" @keyup.enter="load" />
<el-select v-model="query.categoryId" clearable placeholder="分类" style="width: 160px">
<el-option v-for="item in categories" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-select v-model="query.status" clearable placeholder="状态" style="width: 140px">
<el-option label="上架" :value="1" />
<el-option label="下架" :value="0" />
</el-select>
<el-button type="primary" @click="load">查询</el-button>
<el-button type="success" @click="open()">新增鲜花</el-button>
</div>
<el-table :data="list" style="width: 100%">
<el-table-column label="封面" min-width="90">
<template #default="{ row }"><img class="cover-img" :src="row.cover" alt="" /></template>
</el-table-column>
<el-table-column prop="name" label="名称" min-width="160" />
<el-table-column prop="categoryName" label="分类" min-width="120" />
<el-table-column prop="flowerLanguage" label="花语" min-width="140" />
<el-table-column prop="price" label="售价" min-width="90" />
<el-table-column prop="stock" label="库存" min-width="80" />
<el-table-column prop="sales" label="销量" min-width="80" />
<el-table-column label="状态" min-width="90">
<template #default="{ row }">{{ row.status === 1 ? '上架' : '下架' }}</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" min-width="180" />
<el-table-column label="操作" min-width="150">
<template #default="{ row }">
<el-button link type="primary" @click="open(row)">编辑</el-button>
<el-button link type="danger" @click="remove(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pager">
<el-pagination background layout="total, prev, pager, next" :total="total" v-model:current-page="query.pageNum" :page-size="query.pageSize" @current-change="load" />
</div>
<el-dialog v-model="visible" :title="form.id ? '编辑鲜花' : '新增鲜花'" width="680px">
<el-form :model="form" label-width="90px">
<el-form-item label="名称"><el-input v-model="form.name" /></el-form-item>
<el-form-item label="分类">
<el-select v-model="form.categoryId" style="width: 100%">
<el-option v-for="item in categories" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="封面"><ImageUpload v-model="form.cover" /></el-form-item>
<el-form-item label="花语"><el-input v-model="form.flowerLanguage" /></el-form-item>
<el-form-item label="售价"><el-input-number v-model="form.price" :min="0" :precision="2" /></el-form-item>
<el-form-item label="原价"><el-input-number v-model="form.originalPrice" :min="0" :precision="2" /></el-form-item>
<el-form-item label="库存"><el-input-number v-model="form.stock" :min="0" /></el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio :value="1">上架</el-radio>
<el-radio :value="0">下架</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="详情"><el-input v-model="form.detail" type="textarea" :rows="4" /></el-form-item>
</el-form>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="save">保存</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import ImageUpload from '../../components/ImageUpload.vue'
import { categoryList, flowerDelete, flowerPage, flowerSave, flowerUpdate } from '../../api/admin'
const list = ref([])
const total = ref(0)
const categories = ref([])
const visible = ref(false)
const query = reactive({ pageNum: 1, pageSize: 10, name: '', categoryId: null, status: null })
const form = reactive(blank())
/**
* 空表单
*/
function blank() {
return { id: null, name: '', categoryId: null, cover: '', flowerLanguage: '', price: 0, originalPrice: 0, stock: 0, status: 1, detail: '' }
}
/**
* 加载鲜花和分类
*/
async function load() {
const res = await flowerPage(query)
list.value = res.data.records
total.value = res.data.total
}
/**
* 打开编辑弹窗
*/
function open(row) {
Object.assign(form, row ? { …row } : blank())
visible.value = true
}
/**
* 保存鲜花
*/
async function save() {
if (form.id) await flowerUpdate(form)
else await flowerSave(form)
ElMessage.success('保存成功')
visible.value = false
load()
}
/**
* 删除鲜花
*/
async function remove(row) {
await ElMessageBox.confirm('确认删除该鲜花吗?', '提示')
await flowerDelete(row.id)
ElMessage.success('删除成功')
load()
}
onMounted(async () => {
categories.value = (await categoryList()).data
load()
})
</script>
网硕互联帮助中心









![C++入门篇(十):string(上)——认识string:构造与三大遍历(一条龙讲透operator[]、迭代器、auto、范围for)-网硕互联帮助中心](https://www.wsisp.com/helps/wp-content/uploads/2026/10/20261001032318-6abdd226d398f.png)



评论前必须登录!
注册