ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

美容院会员管理系统源码部署与二次开发指南

美容院会员管理系统源码部署与二次开发指南 简介面向美容院、水疗会所等门店经营场景的会员管理系统源码同时覆盖电脑端管理后台和微信端方便门店管理者直接部署使用也适合后端开发人员作为权限设计与业务功能实现的参考项目。系统权限可细分到每个功能节点会员、套餐、订单等常用数据的增删改查一应俱全并内置电子表格导出能力便于基于会员信息生成经营报表。压缩包共1601个文件整体体积约23.4MB文件类型以PHP、HTML、JavaScript、CSS等典型网页开发文件为主同时包含大量GIF、PNG、JPG图片素材与配置文件并附有安装引导和数据库SQL脚本从环境配置到页面展示环节完整。前台页面与后台逻辑分区明确微信端、公共函数、模板样式等模块相对独立二次开发时容易定位。目前已有3256人学习下载既可以直接部署用于门店日常管理也可以按模块阅读源码深入理解权限细分到功能按钮、基础增删改查和电子表格导出功能的完整实现整体是可落地、可扩展的参考资源。1. 美容院会员管理系统这套源码能解决什么问题先直接说结论美容院会员管理系统源码不是让你从零搭平台而是把门店收银和微信端会员自助之间最麻烦的那层业务已经拆好了。上一轮交付的微信小程序源码工程功能做得再全也没法像网页那样在电脑浏览器里直接打开必须在微信开发者工具里编译运行这是很多人拿到包后的第一个误解。这套源码管的事很具体后台维护会员档案、开卡、充值、记消耗、算员工提成微信端让顾客自己查余额、看消费记录、接收到期和续卡提醒。适合单店美容院和皮肤管理工作室直接上线也适合想拿一套完整业务骨架做课程设计或二次开发的人来参考。2. 后台与微信端的整体拆解六个模块和一条数据主线2.1 后台的六个模块对应店铺的真实动作拿到这类源码包第一件事不是看代码而是把后台菜单翻一遍。美容院会员管理系统基本绕不开六个模块会员管理、卡片管理、充值赠送、消费记录、员工提成、系统设置。这个分布不是凑的拆开看每一块都对应店里每天发生的动作。前台开卡对应会员管理和卡片管理顾客充值对应充值赠送项目做完划卡扣费对应消费记录月底结算对应员工提成店铺名称和微信支付参数归系统设置。模块之间的关系用一张表说清楚这也是后续加功能时判断数据往哪张表放的依据后台模块对应主表核心字段会员管理membermobile 唯一索引、name、birthday、source卡片管理card_type / member_cardbalance、total_count、used_count充值赠送recharge_rule / balance_logrule_name、gift_amount、min_amount消费记录consumption_logbefore_balance、after_balance、card_id员工提成staff / commission_lograte、base_amount、order_id系统设置settingstore_name、appid、mch_id顺着这张表能看到一条主线member 表是根member_card 挂在它下面balance_log 和 consumption_log 记录每张卡的进出账commission_log 再引用消费记录算提成。所以这套系统里最敏感的表就是前四张。源码里如果余额变化直接 update member_card 而不写流水那要警惕一旦出纠纷没有流水根本没法回溯。2.2 微信端只承担三件事自助查询、预约与提醒微信端在美容院场景里不做收银它只干三件没有收银员参与的事查余额与消费明细、提交预约、接收到期提醒。后台是写端微信端是读端加少量写操作。页面结构因此很轻首页展示店铺和技师会员页显示持有的卡和余额明细页列消费记录预约页提交时间我的页面绑定手机号。微信端与后端通信走 JSON 接口小程序用 wx.request 请求。调试期可以勾选“不校验合法域名”真要上线就必须在微信公众平台配置服务器域名并且要求 HTTPS。接口层一般收口在一个 api.js 文件里我习惯先看这个文件确认接口路由和 baseUrl 有没有集中管理。// 小程序端请求封装常见源码包中 utils/request.js 的通用写法 const BASE_URL https://api.example.com; // 部署后替换成自己的域名 function request(path, data {}, method POST) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL path, method: method, data: data, header: { Content-Type: application/json }, success(res) { if (res.statusCode 200 res.data.code 0) { resolve(res.data.data); } else { reject(res.data.message || 请求失败); } }, fail(err) { reject(err.errMsg); } }); }); }这里的前后端约定是 code 为 0 表示业务成功非 0 为业务失败网络层错误走 fail。BASE_URL 在一个文件里统一维护测试环境切正式环境只需要改这一处。注意 res.data.code 的判断不能省——有些后端在业务异常时也返回 HTTP 200只看 statusCode 会漏掉“卡已过期”这类业务错误。2.3 一次开卡背后的数据链路三张表必须同时成功开卡动作看起来是写一条记录实际牵动三张表。以典型 PHP 后端为例流程是往 member 表插入会员档案拿到自增主键 member_id往 member_card 插入卡实例卡号按规则生成余额初始为 0最后往 balance_log 写一条初始流水比如“开卡赠送 0 元”或“首次充值 1000 元”。这三步必须在同一个事务里否则中途报错会出现“人有卡无”的脏数据。// 一次开卡的事务边界会员档案 卡实例 初始流水 $pdo-beginTransaction(); try { $stmt $pdo-prepare( INSERT INTO member (name, mobile, store_id, created_at) VALUES (:name, :mobile, :store_id, NOW()) ); $stmt-execute([ :name $name, :mobile $mobile, :store_id $storeId, ]); $memberId $pdo-lastInsertId(); $cardNo C . date(Ymd) . rand(1000, 9999); $stmt $pdo-prepare( INSERT INTO member_card (member_id, card_type_id, card_no, balance, created_at) VALUES (:mid, :tid, :cno, 0, NOW()) ); $stmt-execute([:mid $memberId, :tid $cardTypeId, :cno $cardNo]); $pdo-commit(); } catch (Exception $e) { $pdo-rollBack(); throw $e; }这个事务的关键点有两个。第一member_id 来自 lastInsertId不能手动拼一个数字否则主外键分叉会员档案和卡片对不上。第二card_no 用 rand(1000, 9999) 生成单店低并发没问题多店并发会撞号我一般建议加上数据库唯一索引兜底或者换成 uniqid(C, true)。参数说明store_id 在单店场景固定为 1多店连锁时引入 store 表把员工、卡和消费记录都挂到店铺维度。card_type_id 决定卡的类型储值卡的 balance 是金额次卡的 balance 通常存剩余次数年卡靠 expire_at 控制有效期。类型之间不能混用逻辑这也是卡片类型表必须单独维护的原因。消费流水同理每条记录都要保存操作前后的余额方便后续对账和纠纷处理。3. 开卡、充值、计次的落地实现让账目从进店到离店闭环3.1 储值卡、次卡、年卡、体验卡字段设计决定后期改不改表美容院会员卡形态比健身房更杂常见就有四种储值卡按金额扣次卡按次数扣年卡按有效期体验卡用来拉新。源码里如果让它们共用一张 member_card 表就必须靠 card_type 区分。我拆过的包多数是这样设计的卡类型关键字段扣费逻辑过期逻辑储值卡balance 金额余额消费时扣 balance一般不过期次卡total_count / used_count每次 used_count1可设 expire_at年卡start_at / expire_at不扣次数不扣钱到期自动停用体验卡折扣率字段结算按折扣计算过期或限用一次字段确定后后台“开卡”页面就是在组一条记录选会员、选卡类型、填金额或次数、选赠品或折扣、写备注。界面再怎么变落到后端就是一次事务复用的是 2.3 节那套逻辑。提示card_type 表尽量保留一个 is_deleted 字段下架旧卡种时做软删除避免历史流水外键断掉。3.2 充 1000 送 200 的规则为什么必须放在后端计算充值赠送是美容院用得最多的营销也是最容易翻车的地方。常见错误是前端页面写死规则比如 [{“amount”:1000,“gift”:200},{“amount”:3000,“gift”:800}]用户输入金额后前端算好到账数提交。这种写法有两个问题第一规则写在页面里店长调整活动就得改代码发版本第二前端计算的金额可以被构造直接把到账金额改成 5000 提交后端一旦照单全收就亏了。正确做法是后端保存规则前端只提交实付金额赠送由服务端计算。// 充值规则判断前端只传实付金额赠送金额由后端计算 function calcGift($payAmount, $rules) { $gift 0; foreach ($rules as $rule) { if ($payAmount $rule[min_amount]) { $gift $rule[gift_amount]; // 命中当前最高档继续循环匹配更大档位 } } return $gift; }这里要强调的是规则表里的 min_amount 和 gift_amount 一定要能在后台维护而不是写死在代码里。我见过一些源码把赠费档位放进常量店长想改活动只能找人来改文件小程序端改一次还得等审核半天就耗进去了。把规则挪到数据库后后台改完接口即时生效微信端不用发版。3.3 次卡扣减与并发一个人同时划两次卡会出什么问题次卡扣减的坑比储值卡更隐蔽。储值卡更新余额时用 set balance balance - 100 这种 SQL天然防并发次卡如果先读 used_count算好新值再写回两个请求同时进来都读到 used_count 1各自写成 2实际只扣了一次卡却显示少了两次。-- 正确做法用条件更新替代“先查后改” UPDATE member_card SET used_count used_count 1 WHERE id :cardId AND used_count total_count AND (expire_at IS NULL OR expire_at NOW()); -- 受影响行数为 0 时表示次数已用完或卡已过期这段 SQL 的精髓在 WHERE 条件。used_count total_count 保证不会扣成负数expire_at 判断保证过期卡不能继续划。后端拿到影响行数为 0 时应该返回“次数不足”或“卡已过期”而不是直接提示成功。再把扣次数和写消费记录包在同一个事务里就能避免超扣和流水缺失两边对不上的情况。这里的并发问题不是玄学就是锁和条件更新用得不彻底。4. 微信端常见问题排查登录、白屏与回调的四次翻车4.1 登录接口报 40029code 换 session_key 的时效问题现象小程序端 wx.login 拿到 code传给后端调微信接口换 openid 和 session_key返回错误码 40029提示 code 无效。真机偶发开发者工具里正常。原因code 是一次性的有效期五分钟且只能用一次。只要前端对同一个 code 发起两次换 openid 的请求第二次必然报 40029。另一种常见情况是前端把 code 存到一个全局变量里反复使用页面刷新后没有重新调 wx.login。解决前端每次登录都重新执行 wx.login 拿新 code后端不要缓存 code。正确流程是wx.login 拿 code → 后端换 openid → 根据 openid 查 member 表拿会员信息 → 签发自有 token 返回前端。token 有效期建议设一周太久的话顾客换手机后登录态容易混乱。4.2 开发者工具正常、真机白屏ES6 转换与基础库版本现象源码在开发者工具里预览一切正常上传体验版后真机打开白屏控制台报某个语法错误或找不到 xxx。原因两个问题叠加。第一开发者工具默认开启“ES6 转 ES5”掩盖了源码里不兼容的箭头函数或模板字符串第二真机基础库版本过低Promise 或某些 API 不可用。解决打开项目详情把“ES6 转 ES5”先关掉重新编译看哪里报错再逐行改成兼容写法。同时把最低基础库版本设为 2.10.0 以上老手机上版本过低时优先提示用户升级微信而不是堆 polyfill。另外注意有些源码依赖的地图、支付、订阅消息组件是插件形式插件没在 app.json 里声明真机也会白屏。提示真机白屏时优先打开 vConsole 面板报错信息比逐行读代码更能定位问题。4.3 图片上传失败合法域名和临时文件路径一起查现象微信端上传头像或消费凭证开发者工具里选图上传成功真机报 uploadFile:fail。原因大概率两类。第一后台接口域名没有配进小程序后台的 uploadFile 合法域名列表第二图片临时路径被缓存第二次选同一张照片时用的还是旧路径。解决先在微信公众平台的“开发管理”里把 uploadFile 合法域名和 request 合法域名都加上。临时文件路径不要缓存每次选图后都拿 res.tempFilePaths 的最新值。后端接收文件时PHP 常见的坑是服务器 upload_tmp_dir 权限不够导致 move_uploaded_file 返回 false接口报成功但图片没落库。查日志才能发现权限问题。4.4 支付回调验签失败金额单位、空参数与证书路径现象微信端下单成功顾客付款正常但后台订单状态不更新日志里出现签名错误。原因支付回调验签有三个常见原因叠在一起。第一金额单位错前端传元后端按分处理签名串和回调内容不一致第二回调数据里没有过滤空值把空参数也拼进签名串第三源码里带的证书路径是作者本机的绝对路径部署后找不到文件。解决金额内部统一用“分”做单位出参给前端时才转成元。验签时按微信官方规则过滤空值和 sign 字段再按字典序拼接。证书路径不要写绝对路径改成相对于项目根目录的路径部署时用软链或环境变量注入。商家号 mch_id、API 密钥和证书也必须替换成自己的这不是可选项是上线前置条件。5. 部署与初始化把源码包变成能跑起来的店铺后台5.1 环境与目录结构先分清后端工程和小程序工程源码包通常包含两个工程管理后台和微信小程序。解压后先看根目录有没有 README没有也不慌用目录结构判断。一般会有 backend 或 api 目录放后端miniapp 或 weapp 目录放小程序。管理后台可能是接口项目加独立前端页面也可能是一个完整网页项目。我习惯先在根目录搜 config 关键字定位数据库配置文件和小程序接口配置文件这是整个部署地图的起点。后端常见 ThinkPHP 或类似 MVC 框架入口 index.php 在 public 下application 或 app 目录放控制器和模型config 目录放数据库与微信配置。小程序端有 project.config.json 标识工具版本app.js 里调登录utils/request.js 管网络请求。不要一上来就改业务代码先把两个工程各自跑通再谈功能调整。5.2 数据库初始化与配置文件SQL 导入和账号修改初始化数据库这步顺序很关键。很多包自带 SQL 文件放在根目录的 sql 或 database 目录里。先建库再导入然后改配置文件。以后端用 PHP 为例数据库配置通常在 config/database.php 或 .env 文件里核心就是主机、端口、库名、账号、密码五项。常见错误是只改库名不改账号密码连不上后去查业务代码白折腾半小时。# 初始化数据库的常见动作先导入表结构再导入初始数据 mysql -uroot -p ./sql/schema.sql mysql -uroot -p ./sql/init_data.sqlschema.sql 建表结构init_data.sql 塞默认的卡类型、充值规则和初始管理员账号。导入后先 SELECT 一下 member 表有没有数据再查 admin 表确认管理员账号存在避免登录时报错。注意init_data.sql 里的管理员密码通常是 123456 明文登录进去第一件事改成 8 位以上混合密码。接口地址配置决定小程序能不能连上后端。小程序端 config 或 app.js 里通常有一个 baseUrl测试时用 http://localhost 不行手机访问不到电脑本机要先用局域网 IP。真机预览时把 baseUrl 改成电脑的局域网地址并在开发阶段勾选“不校验合法域名”真正上线再把域名换成 HTTPS 正式地址。5.3 小程序侧参数替换AppID、服务器域名与体验版小程序跑起来之前有三个位置必须替换少任何一个都会卡在登录或支付环节。第一是 project.config.json 里的 appid源码包自带的是作者测试号不替换会在开发者工具里提示 appid 不匹配。第二是后端配置里的 appid 和 secret必须换成自己的小程序账号。第三是服务器域名走体验版时 request、uploadFile 和 downloadFile 的合法域名都要配不能只配 request。{ appid: wx你的小程序AppID, compileType: miniprogram, setting: { urlCheck: false } }urlCheck 在开发者工具里设为 false 可以跳过域名校验方便本地调试但发布体验版前要改回 true否则真机请求会被微信拦截。appid 替换后记得清缓存重新编译我遇到过替换后白屏最后发现是开发者工具缓存里还在用旧 appid。5.4 上线前检查清单九个动作过一遍再交付我从“能跑”到“敢用”的检查项列一下部署完一项项过数据库自动备份有没有配置管理员初始密码是否已改小程序 appid 和 secret 是否换成正式账号后端域名是不是 HTTPS 且证书未过期request、uploadFile、downloadFile 三组域名是否都配置支付商户号与后端配置是否一致员工账号是否按最小权限分配充值、退款等敏感接口有没有登录态校验消费流水表是否开启定期归档。这些动作看起来琐碎但每一件都对应一次真实事故。给合作店铺做验收时我至少要看到三条线上日志才敢说系统能交付。6. 批量导入老会员Excel 数据补录的最后一个坑6.1 老会员数据先进临时表再进正式表换新系统最现实的问题是老店上百个会员不能靠前台手敲。常见做法是把 Excel 整理成三列手机号、姓名、卡余额导入临时表再通过 SQL 合并进正式表。切忌直接在正式表上逐条执行 INSERTExcel 里一行手机号重复、一行格式错误就会中断整个导入过程。-- 先把 Excel 数据落进临时表 member_import CREATE TEMPORARY TABLE member_import ( mobile VARCHAR(11) PRIMARY KEY, name VARCHAR(50), balance DECIMAL(10,2) ); -- 用 INSERT ... SELECT 把老会员并进正式表 INSERT INTO member (name, mobile, store_id, created_at) SELECT name, mobile, 1, NOW() FROM member_import ON DUPLICATE KEY UPDATE name VALUES(name);临时表有两个作用一是让 Excel 的脏数据在临时表阶段被过滤二是用 ON DUPLICATE KEY UPDATE 解决手机号重复问题重复时只更新姓名不新增档案。再补一步把老会员的余额以初始流水写进 balance_log否则前台看到的余额和系统账本对不上。卡类型字段按老店实际情况填写没有就归到储值卡后续再做调整。6.2 导入后的三个对账点少一个都会出错导入不是跑完 SQL 就结束我习惯再核三遍。第一遍count 临时表行数要和正式表新增行数相等第二遍抽样几个会员核对手机号、姓名和余额三要素第三遍跑一遍 SUM(balance) 对比 Excel 手工表的总额差一分钱都要查出原因再继续。从那以后我每次给店铺部署这套源码导入老会员数据都会强制走一遍临时表加三道对账的流程宁可多花十分钟也不让旧数据把新账本污染掉。希望帮到你。本文还有配套的精品资源点击获取
返回列表