简介:这是一款面向实体店铺与新零售场景的全栈式会员营销系统,适用于汽车4S店、餐饮、花店、甜品店及线上电商等需打通收银与会员运营的中小商户,解决传统系统割裂、营销工具缺失、多端体验不统一等核心问题。资源包共531个文件,含422个Java业务逻辑与控制器类(如CouponServiceImpl、MemberServiceImpl)、50个XML配置与Mapper映射文件、33个PNG与13个JPG界面资源图、以及SQL建表脚本、Shell部署脚本和Properties配置文件,完整覆盖微信小程序前台、H5轻应用、SpringBoot后端API及Vue后台管理四端源码,压缩包仅5.5MB,结构清晰、模块解耦度高。已有693人学习下载,提供开箱即用的优惠券、储值卡、集次卡、电子券、积分体系与聚合支付收款能力,代码规范、注释充分,适合作为Java全栈开发学习范例或本地化快速部署的商业级解决方案。
1. 项目概述:为什么实体店需要一套自己的会员营销系统?
干了十几年零售和软件,我见过太多实体店主在会员管理上踩坑。有的还在用纸质本子登记,客户信息散落各处;有的虽然上了某个大平台的会员功能,但活动规则被平台卡得死死的,数据也不在自己手里,想做个生日营销都束手束脚。所以,当有店主朋友问我,想自己搞一套包含小程序、H5、后台的会员系统到底值不值时,我的回答永远是:如果你真想留住客户、玩转私域,这就是从“坐商”变“行商”的关键一步。
这套系统,简单说,就是给实体店装上一个数字化的“大脑”和“手脚”。前台微信小程序是面向会员的主阵地,用来展示门店、发放优惠券、完成积分兑换和在线储值。H5页面则更灵活,可以用于在微信群里发促销活动链接、做裂变海报、或者作为临时活动页,无需下载,点开即用。后端API是心脏,负责所有业务逻辑和数据处理,比如计算积分、核销优惠券、处理订单。而后台管理系统就是大脑,让你在电脑前就能看清所有会员画像、制定营销策略、分析营业数据。
它解决的核心就三个字:连接、洞察、自动化。连接线上线下,洞察客户行为,自动化营销动作。比如,一个客户半年没来了,系统可以自动给他发一张“好久不见”的专属券;某个商品突然热卖,后台马上能看出是哪些会员带动的销量。这不再是简单的记账工具,而是一个增长引擎。
2. 系统整体架构与核心模块设计思路
2.1 技术栈选型:为什么是它们?
选型没有绝对的对错,只有适合与否。基于实体店项目通常追求快速上线、成本可控、易于维护的特点,我推荐下面这套经过验证的组合拳。
前端(微信小程序 + H5):
- 微信小程序:首选Uni-app或Taro这类跨端框架。为什么?因为实体店系统功能迭代快,你可能今天想做拼团,明天想加直播。用原生小程序开发,iOS和安卓两端都要写,效率低。而Uni-app“一套代码,多端发行”(小程序、H5、App)的特性,能极大降低开发和维护成本。对于UI组件,推荐使用uView(Uni-app生态)或Vant Weapp(Taro/Vue生态),它们封装了丰富的商城组件,如商品卡片、优惠券面板等,能省下大量基础开发时间。
- H5页面:如果主框架用了Uni-app,那H5部分自然就统一了。若独立开发,Vue 3 + Vite是当前最主流、性能最好的选择。UI库方面,Element Plus或Ant Design Vue都足够成熟。但注意,H5在微信环境内会涉及大量JS-SDK调用(分享、支付、定位等),这块的兼容性调试是重点。
后端API:
- 语言与框架:Node.js (Koa/Nest.js)或Java (Spring Boot)是稳妥之选。Node.js适合业务逻辑不极其复杂、需要快速迭代的中小型项目,它对JSON数据处理和异步高并发(如抢券场景)有天然优势。Spring Boot则胜在生态完善、稳健,适合团队技术栈偏Java或对事务一致性要求极高的场景(如涉及复杂的积分、储值清算)。
- 关键考量点:无论选哪种,都必须做好API文档管理(用Swagger或Apifox)和统一的响应封装。实体店活动经常突发,后端API设计要清晰,方便前端和后期可能的第三方对接。
后台管理系统:
- 技术选型:毫无疑问,Vue 3 + Element Plus是目前后台管理开发的最优解。Element Plus组件丰富,文档齐全,社区活跃,能快速搭建出功能完善、体验流畅的管理界面。构建工具用Vite,开发体验飞起。
- 设计核心:后台不是功能的堆砌,而是效率工具。页面设计要围绕“降低操作步骤”和“一眼看清关键数据”展开。比如,会员列表要支持多维度筛选(最后消费时间、消费频次、标签),营销活动创建要用“向导式”界面,一步步引导管理员完成配置。
2.2 前后端分离与数据流设计
现代Web项目几乎都是前后端分离,这套系统也不例外。核心思想是:前端(小程序/H5/后台)负责展示和交互,后端(API服务器)负责提供数据和服务,两者通过HTTP API通信。
关键数据流示例:会员领取优惠券
- 小程序前端:用户点击“领取”按钮。
- 前端调用后端API:
POST /api/coupon/receive,携带优惠券ID和用户Token。 - 后端验证:校验Token合法性、优惠券是否可领(库存、限领张数、用户资格)。
- 后端写库:在
user_coupon表生成一条记录,状态为“未使用”。 - 后端响应:返回成功信息及领取的优惠券详情。
- 前端更新UI:弹窗提示领取成功,并刷新“我的优惠券”列表。
注意:所有涉及资产变动(如发券、扣积分、储值消费)的接口,必须做好幂等性处理。防止因网络抖动导致前端重复请求,造成用户重复领取或扣款。通常在后端通过业务唯一键(如用户ID+活动ID+批次)加锁或检查状态来实现。
3. 核心功能模块深度解析与实现要点
3.1 会员中心:不止于一张卡片
会员模块是根基,设计上要从“身份识别”升级到“用户画像”。
1. 会员成长体系设计:
- 等级计算:不要简单按消费总额定级。我建议采用“成长值”模型。成长值=消费金额系数 + 签到次数系数 + 分享行为*系数。后台可灵活配置系数和等级门槛。这样能激励多元行为,而不仅仅是“砸钱”。
- 权益挂钩:不同等级对应不同权益,如折扣率、生日礼包内容、专属客服、积分加速倍率。这些权益必须在后台可以动态配置,方便运营随时调整。
- 数据表设计核心字段:
CREATE TABLE `member` ( `id` bigint PRIMARY KEY, `user_id` bigint COMMENT '关联的用户ID', `level` tinyint COMMENT '当前等级', `growth_value` int COMMENT '当前成长值', `total_consumption` decimal(10,2) COMMENT '历史总消费', `balance` decimal(10,2) COMMENT '账户余额(储值)', `points` int COMMENT '当前积分', `tags` json COMMENT '会员标签数组,如["常客","喜辣"]', `last_consumption_time` datetime COMMENT '最后消费时间' );
2. 标签系统实现: 标签是精准营销的“弹药”。系统应支持手动打标(如店员标记“VIP”)和自动打标。
- 自动打标规则引擎:在后台配置规则,如“近30天消费满3次”自动打上“活跃客户”标签;“购买过A品类但未买过B品类”打上“潜在交叉销售”标签。这需要一个小型的规则解析器,定时任务(如每天凌晨)跑批处理。
- 应用场景:创建营销活动时,可以直接选择“带有‘活跃客户’标签且没有‘已发送复苏券’标签的会员”作为目标人群,实现精准触达。
3.2 积分与储值:虚拟资产的安全与流通
这是系统的“金融”模块,稳定和安全压倒一切。
1. 积分体系:
- 入账:消费奖励、签到、任务完成。关键是要有明细流水表(
points_flow),记录每一笔积分的来源(业务类型、订单号)、变动数额、剩余数额。这是对账和排查问题的唯一依据。 - 消耗:兑换礼品、抵扣现金。必须做库存和并发控制。热门礼品兑换时,要用分布式锁(如Redis锁)防止超卖。
- 过期与清零:可以在
member表记录积分有效期,或通过流水记录计算。过期逻辑最好由每日定时任务执行,避免在用户查询时实时计算影响性能。
2. 储值(预付费):
- 支付与入账:对接微信支付/支付宝的充值接口。支付成功后,回调通知里要严格校验金额和订单状态,然后再给会员余额加钱。这里必须保证幂等性,防止回调重复触发导致多次加钱。
- 消费与冻结:会员用余额支付时,不能直接扣减余额。标准流程是:先创建支付订单,系统冻结这部分金额,待支付成功后(或一定时间后未取消)再实际扣减。这能有效处理支付中途取消等异常情况。
- 对账:每日需将系统的储值流水与支付平台的交易流水进行对账,确保账实相符。这是硬性要求,不能偷懒。
3.3 营销引擎:让活动自己跑起来
营销模块是系统的价值放大器,核心是可配置化和自动化。
1. 优惠券系统:
- 类型:折扣券、满减券、代金券。表设计要通用化,用字段区分。
- 发放:支持手动发放(后台输入会员号)、自动发放(满足条件触发)、用户主动领取。领取环节要做好频率限制(每人限领几张)和库存扣减。
- 核销:线下核销是小程序端的重点。生成核销二维码(包含券ID和加密信息),店员用管理端小程序扫码,后端验证券状态(是否过期、是否已用、是否属于本店)后完成核销。核销记录同样需要详尽的流水。
2. 自动化营销(营销画布): 这是高阶功能。你可以像搭积木一样设计客户旅程。
- 触发条件:客户完成注册、达到某个等级、生日、超过N天未消费。
- 执行动作:发送微信模板消息、发放一张特定优惠券、打上一个标签。
- 实现:需要设计一个工作流引擎。可以用状态机来实现,将每个会员作为一条实例,在满足条件时推进到下一个节点并执行动作。初期可以用数据库+定时任务轮询的方式简化实现。
4. 关键接口与第三方集成实战
4.1 微信生态深度集成
实体店生意大半在微信里,所以集成必须做深做透。
1. 微信小程序用户登录与获取手机号:
// 前端 (Uni-app示例) uni.login({ success: (res) => { // 1. 获取code const code = res.code; // 2. 将code发送到自己后端 uni.request({ url: '/api/auth/wx-login', method: 'POST', data: { code }, success: (authRes) => { // 3. 后端用code换openid和session_key,生成自定义token返回 // 4. 前端存储token,后续请求携带 } }); } }); // 获取手机号(需要企业认证且用户主动触发) <button open-type="getPhoneNumber" @getphonenumber="onGetPhoneNumber"></button> // 事件回调中会收到加密数据,需传给后端,结合session_key解密实操心得:
session_key敏感且会过期,绝不能传到前端!解密操作务必在后端完成。用户信息(头像昵称)通过<open-data>组件或wx.getUserProfile(新规)获取。
2. 微信支付集成: 这是交易闭环的关键。推荐使用服务商模式(如果你有服务商资格)或直连模式。以后者为例,流程如下:
- 后端统一下单:调用微信支付API,生成
prepay_id。 - 后端再次签名:将必要的参数(如
appId,timeStamp,nonceStr,package,signType)按微信规则签名,返回给前端。 - 前端调起支付:
uni.requestPayment(OBJECT)。 - 处理支付结果:前端支付成功回调仅作UI提示,真实支付结果以后端收到的微信支付异步通知为准。后端回调处理逻辑必须幂等,并更新订单状态、发放积分等。
3. H5微信分享与定位: 在微信内打开的H5,依赖JS-SDK。
- 分享:需要注入配置,并使用
wx.updateAppMessageShareData等API。分享链接最好带上渠道参数(如?share_from=uid_123),便于后续追踪推广效果。 - 定位:使用
wx.getLocation。关键坑点:微信要求定位接口必须由用户手势(如click)触发,且需要在wx.config中声明权限。H5获取的坐标是火星坐标(GCJ-02),如需在地图组件(如腾讯地图、天地图)显示,需确认坐标系是否匹配,不匹配则需转换。
4.2 地图与门店LBS能力
对于多门店或需要展示位置的门店,地图组件必不可少。
- 微信小程序地图:可使用腾讯地图或天地图的小程序SDK。以腾讯地图为例,引入
qqmap-wx-jssdk,先通过wx.getLocation获取用户坐标,再调用SDK进行地点搜索、路线规划等。 - H5地图:常用腾讯地图JavaScript API。注意,在微信H5中获取的定位,传给腾讯地图API前,通常不需要转换坐标系(因为微信H5返回的也是GCJ-02)。但如果你用的地图API要求WGS-84坐标,那就必须转换。
- 常见问题:“uniapp h5使用腾讯地图获取定位报错: getlocation:fail...” 这类错误,90%是因为在
wx.config时,没有正确配置jsApiList,把getLocation加进去。另外,H5调用定位必须在域名完成备案且配置了JS接口安全域名后才行。
5. 后台管理系统搭建实战与优化
后台是运营人员的战场,效率第一。
5.1 基于Vue3+Element Plus的快速搭建
- 项目初始化:使用
Vite创建Vue3项目,安装Element Plus。npm create vue@latest my-admin cd my-admin npm install element-plus @element-plus/icons-vue - 按需引入:为减小打包体积,推荐使用自动导入插件(如
unplugin-vue-components、unplugin-auto-import),这样在模板中直接写<el-button>就能用,无需手动import组件和样式。 - 布局与路由:采用经典的左右布局(侧边栏导航+主内容区)。使用Vue Router管理路由,配合
<router-view>渲染页面。侧边栏菜单建议根据登录用户的权限动态生成。
5.2 复杂数据表格与表单处理
后台最多的就是表格和表单。
1. 高性能表格渲染: 当会员数据上万条时,前端渲染不能一次性全量加载。必须实现:
- 后端分页:API接口接受
page(页码)、size(每页条数)参数,返回对应数据及总数。 - 前端搜索与筛选:表格顶部提供搜索框和筛选器,输入条件后,重新请求第一页数据。
- Element Plus技巧:使用
<el-table>时,给大量数据的列加上show-overflow-tooltip属性,避免单元格内容过长撑开布局。对于固定列、排序、自定义列模板等功能,要熟练掌握。
2. 向导式营销活动创建表单: 一个完整的促销活动(如“满减送”)包含基础信息、规则设置、推广渠道等多步信息。用多个<el-form>组件,通过一个变量(如activeStep)控制显示哪一步。每一步表单数据用Vuex或Pinia全局状态管理,最后一步统一提交。这样用户体验清晰,也降低了单次表单的复杂度。
5.3 数据可视化与报表
老板最爱看图表。集成ECharts或AntV来制作仪表盘。
- 核心指标:今日营业额、新增会员数、优惠券核销率、会员消费TOP10。
- 实现:在后端编写专门的数据聚合接口,前端定时(如每5分钟)或手动调用接口获取数据,更新图表。对于需要复杂计算的数据(如“会员复购率”),建议在后端计算好再返回,减轻前端压力。
6. 开发部署全流程与避坑指南
6.1 开发环境与联调
- API管理:强烈推荐使用Apifox或YApi。前后端先定义好API接口文档(请求/响应格式、错误码),然后前后端并行开发。后端可以开启Mock服务,让前端不依赖后端进度也能开发界面。
- 小程序真机调试:微信开发者工具的“真机调试”功能必不可少。很多样式和API问题(如摄像头调用)在模拟器上正常,在真机上才暴露。
- H5调试:在微信内打开H5,可以使用
vConsole或eruda等移动端调试面板注入工具,方便查看日志、网络请求。
6.2 部署上线与运维
- 后端部署:推荐使用Docker容器化部署。编写
Dockerfile和docker-compose.yml,将应用、Redis、MySQL等服务编排在一起。这样部署环境一致,迁移方便。 - 前端部署:
- 小程序:通过微信开发者工具上传代码,提交审核。注意域名白名单:小程序请求的后端API域名、图片域名等,都需在小程序管理后台配置到“request合法域名”和“downloadFile合法域名”中。
- H5:打包后(
npm run build)的dist目录,部署到Nginx或对象存储(如阿里云OSS、腾讯云COS)并绑定域名。 - 后台管理:同样部署到Web服务器,并设置访问权限(如IP白名单、登录认证),避免被公开访问。
- HTTPS:小程序和微信内H5强制要求服务端使用HTTPS。申请SSL证书(很多云平台提供免费证书),并在Nginx中配置。
6.3 常见问题排查实录
问题1:小程序上线后,部分用户无法登录/获取头像。
- 排查:检查小程序是否已发布到线上版本。检查
wx.login和wx.getUserProfile的调用时机是否符合微信最新规范(不能一启动就调用,需在用户交互后)。查看后端解密session_key的逻辑是否正确,特别是用户session_key过期后,需要用code重新登录。
问题2:H5在微信分享时,自定义标题和图片不生效。
- 排查:首先确保已正确引入JS-SDK,且
wx.config的签名计算无误(签名用的url必须是当前页面的完整URL,不能是location.href去掉#的部分)。其次,分享接口(如wx.updateAppMessageShareData)必须在wx.ready回调中调用。最后,检查分享的图片链接是否支持HTTPS且能被微信爬虫抓取。
问题3:后台管理系统打开缓慢,特别是报表页面。
- 排查:前端检查是否打包了过大的依赖(如整个ECharts),改用按需引入。使用Chrome DevTools的
Performance和Network面板分析加载瓶颈。后端检查数据聚合接口的SQL查询是否优化,是否加了必要的数据库索引。考虑对不常变化的报表数据(如昨日数据)进行缓存。
问题4:优惠券超领或超核销。
- 根本原因:高并发下的库存或状态判断竞态条件。
- 解决方案:在“领取”和“核销”的关键业务逻辑上,使用分布式锁。以领取为例,伪代码如下:
// 伪代码,使用Redis分布式锁 String lockKey = "coupon:receive:" + couponId + ":" + userId; boolean locked = redis.setnx(lockKey, "1", 10); // 尝试加锁,10秒超时 if (locked) { try { // 1. 查询优惠券库存和用户已领数量(需在事务内或使用原子操作) // 2. 判断是否可领 // 3. 扣减库存,增加用户领取记录 } finally { redis.del(lockKey); // 释放锁 } } else { throw new BusinessException("请求过于频繁,请稍后再试"); }
开发这样一套系统,最大的挑战往往不是某个具体的技术点,而是对线下实体业务的理解和抽象。技术是实现手段,核心是为“人”(店员、会员)和“货”(商品、服务)建立高效、温暖的数字连接。从第一行代码开始,就要想着如何让店员操作少点一下,让会员感觉更被关心一点。这些细节的累积,才是系统真正产生价值的地方。
本文还有配套的精品资源,点击获取