核心定位:轻医美/养生门店的门店、员工、客户档案管理,并提供 WordPress 用户同步 API。
本项目采用 双重授权模式(Dual License):
-
开源学习与非商业用途 采用 GNU AGPLv3 (或 GNU GPLv3) 许可证。您可以自由地阅读、修改和分发本代码用于个人学习、学术研究或开源项目,但前提是您的衍生项目也必须遵循 AGPLv3/GPLv3 协议完全开源。
-
商业用途 本项目的 AGPLv3/GPLv3 协议不适用于任何闭源的商业行为(包括但不限于:作为闭源产品出售、作为SaaS服务的底层系统等且拒绝开源自身代码)。如果您希望将本系统用于商业盈利目的而不愿开源您的代码,请务必联系作者购买商业授权版本。
未经购买商业授权而将本项目用于闭源商业用途的,我们将保留追究法律责任的权利。
目前商用授权9.9元人民币。
- 邮箱: iticu@qq.com
- QQ群: 16966111
- PHP 8.2
- MariaDB 10.11
- Apache
- Docker Compose 一键部署
推荐安装方式:直接访问安装向导:
/install.php
安装向导支持:
- 环境检测(PHP版本、扩展、目录可写、关键文件可读)
- 输入数据库地址/库名/账号/密码
- 输入管理员账号信息
- 自动创建数据库与表、初始化默认数据、写入
.env
性能说明:
- 运营报表相关复合索引(订单、支付、客户、预约、次卡流水等)。
- 老系统升级建议优先使用命令行安装脚本:
php scripts/install.php(会自动补齐缺失索引与表结构)。 - 提供执行计划检查脚本:
scripts/explain_reports.sql(用于 EXPLAIN 级别调优)。
注意:
- 安装成功后会自动生成安装锁文件:
storage/install.lock,默认禁止再次网页安装。 - 若确需重装,请先手工删除
storage/install.lock后再访问install.php。
安装完成后,根路径 / 会显示系统介绍首页。
可在后台「高级模块 -> 系统安全设置」控制:
- 前台是否开放
- 前台维护文案
- 前台 IP 白名单
- 是否启用安全响应头
安装完成后默认访问:
/admin/
说明:
- 这是前后端分离式管理台:页面在入口地址,数据通过
/api/v1/*获取。 - 首次登录使用安装向导中你设置的管理员账号密码。
- 可在后台「高级模块 -> 系统安全设置」自定义后台入口路径(例如改成
/qiling-center-2026)。 - 入口变更后,默认
/admin会被隐藏(返回 404)。 - 后台面板已覆盖:经营总览、主数据、业务运营、代客操作、积分营销、支付打印、回访推送、高级模块(转赠/开单/开单礼/提成/WP同步/Cron/用户端二维码与口令管理)、报表中心、API调试台。
确保站点 root 指向 public/,并加入:
location = /admin {
rewrite ^ /index.php last;
}
location = /admin/ {
rewrite ^ /index.php last;
}
location = /admin/index.html {
rewrite ^ /index.php last;
}
location = /pay {
try_files /pay/index.html /index.php?$query_string;
}
location = /pay/ {
try_files /pay/index.html /index.php?$query_string;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}
默认读取 .env:
INSTALL_ADMIN_USERNAME(默认admin)INSTALL_ADMIN_PASSWORD(建议安装后置空)- 默认角色:
admin(全局门店权限) CRON_SHARED_KEY:外部定时任务访问密钥(安装向导会自动生成)TRUST_PROXY_HEADERS:是否信任X-Forwarded-For/X-Real-IP(默认false,仅在反向代理场景下建议开启)
- 登录防暴力破解:
LOGIN_MAX_FAILED_ATTEMPTS:连续失败上限(默认5)LOGIN_LOCK_SECONDS:达到上限后锁定秒数(默认900秒)
- 员工账号不提供自助找回密码;只能由管理员在后台“账号用户”中重置密码。
- 管理员忘记密码时,使用命令行恢复(不会开放公开找回接口):
php scripts/reset-admin-password.php --list
php scripts/reset-admin-password.php --username=admin
php scripts/reset-admin-password.php --username=admin --password='新密码至少6位'- 恢复脚本会自动清空该账号登录失败次数和锁定状态,并输出临时密码(如未手动指定)。
- 地址:
/mobile/ - 适用:员工手机端快速完成客户建档、代客操作、消费记录查询
- 支持按
role_key配置移动端菜单(系统设置中维护mobile_role_menu_json) - 功能聚焦:
- 客户建档(含赠送余额)
- 代客登记消费(扣余额/扣券/扣次)
- 余额调整、次卡调整、发券
- 客户消费记录与订单记录查看
- 菜单配置示例:
{
"default": {
"tabs": ["onboard", "agent", "records"],
"subtabs": {
"onboard": ["onboard_form", "onboard_help"],
"agent": ["consume", "wallet", "card", "coupon"],
"records": ["assets", "consume", "orders"]
}
},
"consultant": {
"tabs": ["agent", "records"],
"subtabs": {
"agent": ["consume", "card"],
"records": ["assets", "consume"]
}
}
}- 地址:
/customer/ - 适用:客户扫码后查看自己的基础资料、会员卡、优惠券、消费记录、订单记录
- 隐私限制:
- 门店内部备注(
notes)不会返回给用户端 - 用户端仅展示客户可见字段
- 门店内部备注(
- 扫码方式:
- 后台菜单:
用户端入口 - 使用“生成客户扫码链接”创建专属链接与二维码
- 客户扫码即可进入自己的资料页
- 后台菜单:
- 后台口令管理:
- 管理员可直接“重置客户访问口令”(用户忘记口令时使用)
- 管理员可按客户解锁口令失败锁定(不会误伤同 IP 其他用户)
- 入口:
GET /pay或GET /pay/index.html - 用途:展示在线支付单(订单号、金额、支付二维码、状态)
- 支持多支付单:URL 可带
ticket或tickets(逗号分隔),例如/pay/?tickets=t1,t2,t3 - 数据接口:
GET /api/v1/payments/public/status?ticket=...POST /api/v1/payments/public/statuses(批量;支持sync_pending=1自动补偿查单)
优先推荐在后台配置:收银与退款 -> 支付配置(管理员权限)。
也可在 .env 中预置默认值:
ALIPAY_ENABLED/WECHAT_ENABLED:是否启用ALIPAY_APP_ID、ALIPAY_PRIVATE_KEY、ALIPAY_PUBLIC_KEYALIPAY_WEB_ENABLED、ALIPAY_F2F_ENABLED、ALIPAY_H5_ENABLED、ALIPAY_APP_ENABLEDALIPAY_NOTIFY_URL(可留空,默认{APP_URL}/api/v1/payments/alipay/notify)ALIPAY_RETURN_URL(可留空)WECHAT_APP_ID、WECHAT_MCH_ID、WECHAT_SECRET、WECHAT_API_KEYWECHAT_JSAPI_ENABLED、WECHAT_H5_ENABLEDWECHAT_NOTIFY_URL(可留空,默认{APP_URL}/api/v1/payments/wechat/notify)WECHAT_ORDERQUERY_URL、WECHAT_CLOSEORDER_URL、WECHAT_REFUND_URL(通常用默认值)WECHAT_REFUND_NOTIFY_URL(可选)WECHAT_CERT_PATH、WECHAT_KEY_PATH(微信退款必填,双向证书)WECHAT_CERT_PASSPHRASE(可选)
说明:
- 当前微信支付实现采用
API v2(统一下单 + XML 回调签名)。 - 线上环境建议使用 HTTPS 公网地址作为回调地址。
- 支付宝密钥支持两种格式:完整 PEM(含
BEGIN/END)或单行密钥字符串;.env中可用\n表示换行。 - 微信退款支持两种证书方式:后台直接粘贴 PEM 内容,或
.env指定WECHAT_CERT_PATH/WECHAT_KEY_PATH文件路径。 - 支付场景:支付宝支持
auto/f2f/page(web)/wap(h5)/app;微信支持native/jsapi/h5。 - 支付宝
auto:优先尝试当面付(f2f),若账号无当面付权限会自动回退到网页支付(page)。
GET /healthPOST /api/v1/auth/loginGET /api/v1/customer-portal/overview(客户扫码入口)POST /api/v1/customer-portal/token/rotate(客户自助修改访问口令,4-6位数字)POST /api/v1/customer-portal/appointments/create(客户在线预约)POST /api/v1/customer-portal/payments/create(用户端在线支付下单)POST /api/v1/customer-portal/payments/sync(用户端在线支付状态同步)POST /api/v1/customer-portal/payments/sync-pending(用户端批量同步待支付单)POST /api/v1/payments/alipay/notifyPOST /api/v1/payments/wechat/notifyGET|POST /api/v1/cron/followup/generate(外部定时任务)GET|POST /api/v1/cron/followup/notify(外部定时任务)GET|POST /api/v1/cron/followup/run(外部定时任务:生成+推送)
GET /api/v1/auth/meGET /api/v1/mobile/menuGET /api/v1/customer-portal/tokensPOST /api/v1/customer-portal/tokens/createPOST /api/v1/customer-portal/tokens/resetPOST /api/v1/customer-portal/tokens/revokeGET /api/v1/customer-portal/guardsPOST /api/v1/customer-portal/guards/unlockGET /api/v1/dashboard/summaryGET /api/v1/storesPOST /api/v1/storesGET /api/v1/staffPOST /api/v1/staffGET /api/v1/customersPOST /api/v1/customersGET /api/v1/servicesPOST /api/v1/servicesGET /api/v1/service-categoriesPOST /api/v1/service-categoriesPOST /api/v1/service-categories/updateGET /api/v1/service-packagesPOST /api/v1/service-packagesGET /api/v1/member-cardsPOST /api/v1/member-cardsPOST /api/v1/member-cards/consumeGET /api/v1/member-card-logsGET /api/v1/ordersPOST /api/v1/ordersPOST /api/v1/orders/payGET /api/v1/order-itemsGET /api/v1/order-paymentsGET /api/v1/payments/configPOST /api/v1/payments/configPOST /api/v1/payments/online/createPOST /api/v1/payments/online/create-dual-qrGET /api/v1/payments/online/statusGET /api/v1/payments/public/statusPOST /api/v1/payments/public/statusesPOST /api/v1/payments/online/queryPOST /api/v1/payments/online/closePOST /api/v1/payments/online/refundGET /api/v1/payments/online/refundsGET /api/v1/admin/customers/searchPOST /api/v1/admin/customers/onboardPOST /api/v1/admin/customers/consume-recordPOST /api/v1/admin/customers/consume-record-adjustPOST /api/v1/admin/customers/wallet-adjustPOST /api/v1/admin/customers/coupon-adjustPOST /api/v1/admin/member-cards/adjustPOST /api/v1/admin/member-cards/manual-consumePOST /api/v1/admin/appointment-consumes/adjustGET /api/v1/appointmentsPOST /api/v1/appointmentsPOST /api/v1/appointments/statusGET /api/v1/followup/plansPOST /api/v1/followup/plansGET /api/v1/followup/tasksPOST /api/v1/followup/tasks/statusPOST /api/v1/followup/generatePOST /api/v1/followup/notifyGET /api/v1/push/channelsPOST /api/v1/push/channelsPOST /api/v1/push/testGET /api/v1/push/logsGET /api/v1/commission/rulesPOST /api/v1/commission/rulesGET /api/v1/performance/staffGET /api/v1/reports/operation-overviewGET /api/v1/reports/revenue-trendGET /api/v1/reports/channel-statsGET /api/v1/reports/service-topGET /api/v1/reports/payment-methodsGET /api/v1/reports/store-dailyGET /api/v1/reports/customer-repurchaseGET /api/v1/customer-gradesPOST /api/v1/customer-gradesGET /api/v1/customer-points/accountGET /api/v1/customer-points/logsPOST /api/v1/customer-points/changeGET /api/v1/open-giftsPOST /api/v1/open-giftsPOST /api/v1/open-gifts/triggerGET /api/v1/coupon-groupsPOST /api/v1/coupon-groupsGET /api/v1/coupon-group-sendsPOST /api/v1/coupon-groups/sendGET /api/v1/coupon-transfersPOST /api/v1/coupons/transferGET /api/v1/member-card-transfersPOST /api/v1/member-cards/transferGET /api/v1/printersPOST /api/v1/printersGET /api/v1/print-jobsPOST /api/v1/print-jobsPOST /api/v1/print-jobs/dispatchPOST /api/v1/wp/users/syncGET /api/v1/wp/usersGET /api/v1/system/settings(admin)POST /api/v1/system/settings(admin)
admin角色:可跨门店查看和操作数据。- 非
admin角色:自动限制在本人staff_store_id门店内,不能跨店查询/写入。 - 支持隔离的核心模块:门店、员工、客户、服务/套餐、次卡、预约、订单、在线支付、回访、提成、报表、后台手工纠偏。
- 建议前端普通账号不再传
store_id,由后端按登录用户自动归属门店。
适合 UptimeRobot / Better Stack / cron-job.org 这类“定时访问 URL”的平台。
鉴权方式(默认仅请求头):
- Header:
X-QILING-CRON-KEY: 你的CRON_SHARED_KEY - 若确需兼容 Query,请在
.env设置CRON_ALLOW_QUERY_KEY=true
推荐直接用 run(一次完成“生成回访任务 + 推送到钉钉/飞书”):
curl -X POST "http://localhost:8088/api/v1/cron/followup/run" \
-H "X-QILING-CRON-KEY: 你的CRON_SHARED_KEY"可选参数:
store_id:只跑某门店generate_limit:生成阶段扫描上限(默认 200)notify_limit:推送阶段上限(默认 100)channel_ids:指定推送通道列表(如[1,2],会同时推送到多个启用通道)channel_id:指定单个通道(兼容旧参数)retry_failed=1:重试失败推送
示例(每5分钟访问一次):
curl -X POST "http://localhost:8088/api/v1/cron/followup/run" \
-H "Content-Type: application/json" \
-H "X-QILING-CRON-KEY: 你的CRON_SHARED_KEY" \
-d '{"store_id":1,"generate_limit":200,"notify_limit":100,"channel_ids":[1,2]}'POST /api/v1/wp/users/sync- Header:
X-QILING-WP-SECRET: {WP_SYNC_SHARED_SECRET} - Header:
X-QILING-WP-TS: {当前Unix时间戳} - Header:
X-QILING-WP-SIGN: {hash_hmac_sha256(ts + "." + body, WP_SYNC_SHARED_SECRET)}
curl -X POST http://localhost:8088/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"username":"你的管理员账号","password":"你的管理员密码"}'body='{
"users": [
{
"wp_user_id": 1,
"username": "summer",
"email": "summer@example.com",
"display_name": "Summer",
"roles": ["administrator"],
"meta": {"phone":"13800000000"}
}
]
}'
ts=$(date +%s)
sign=$(printf "%s.%s" "$ts" "$body" | openssl dgst -sha256 -hmac "你的WP同步密钥" -hex | awk '{print $2}')
curl -X POST http://localhost:8088/api/v1/wp/users/sync \
-H 'Content-Type: application/json' \
-H 'X-QILING-WP-SECRET: 你的WP同步密钥' \
-H "X-QILING-WP-TS: ${ts}" \
-H "X-QILING-WP-SIGN: ${sign}" \
-d "$body"curl -X POST http://localhost:8088/api/v1/services \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"service_name": "补水护理",
"category": "面部护理",
"supports_online_booking": 1,
"duration_minutes": 60,
"list_price": 299
}'curl -X POST http://localhost:8088/api/v1/service-packages \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"package_name": "补水护理10次卡",
"service_id": 1,
"total_sessions": 10,
"sale_price": 1999,
"valid_days": 365
}'# 开卡
curl -X POST http://localhost:8088/api/v1/member-cards \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer_id": 1,
"package_id": 1
}'
# 核销1次
curl -X POST http://localhost:8088/api/v1/member-cards/consume \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"member_card_id": 1,
"consume_sessions": 1,
"note": "到店护理核销"
}'curl -X POST http://localhost:8088/api/v1/appointments \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"customer_id": 1,
"staff_id": 1,
"service_id": 1,
"start_at": "2026-02-21 10:00:00",
"end_at": "2026-02-21 11:00:00",
"source_channel": "微信",
"notes": "首次体验"
}'说明:若已配置并启用钉钉/飞书推送通道,后台新建预约会自动推送预约通知。
curl -X POST http://localhost:8088/api/v1/appointments/status \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"appointment_id": 1,
"status": "completed",
"member_card_id": 1,
"consume_sessions": 1,
"consume_note": "预约完成自动核销"
}'curl -X POST http://localhost:8088/api/v1/appointments/status \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"appointment_id": 1,
"status": "cancelled"
}'说明:当该预约之前通过 completed + member_card_id 触发过核销时,改为 cancelled/no_show/booked 会自动回退次卡次数,且同一预约只回退一次。
curl -X POST http://localhost:8088/api/v1/followup/plans \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"store_id": 0,
"trigger_type": "appointment_completed",
"plan_name": "默认回访计划",
"schedule_days": [1, 3, 7],
"enabled": 1
}'curl -X POST http://localhost:8088/api/v1/followup/generate \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"limit": 200}'curl -X POST http://localhost:8088/api/v1/push/channels \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"channel_name": "运营群钉钉",
"provider": "dingtalk",
"webhook_url": "https://oapi.dingtalk.com/robot/send?access_token=xxxx",
"security_mode": "sign",
"secret": "SECxxxx",
"keyword": "启灵",
"enabled": 1
}'curl -X POST http://localhost:8088/api/v1/push/test \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"channel_id": 1,
"message": "这是一条测试消息"
}'curl -X POST http://localhost:8088/api/v1/followup/notify \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"channel_ids": [1, 2],
"limit": 100,
"retry_failed": 0
}'说明:retry_failed=1 会重试 failed 与 sending 状态任务(用于恢复中断任务)。
说明:可不传 channel_ids,系统会自动推送到全部已启用渠道(钉钉/飞书可双通道同时推送)。
说明:客户端 POST /api/v1/customer-portal/appointments/create 创建在线预约时,也会自动推送“新预约通知”到所有启用通道。
curl -X POST http://localhost:8088/api/v1/orders \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"customer_id": 1,
"appointment_id": 1,
"order_discount_amount": 50,
"coupon_amount": 20,
"items": [
{
"item_type": "service",
"item_ref_id": 1,
"qty": 1,
"unit_price": 299,
"discount_amount": 0,
"staff_id": 1
}
]
}'curl -X POST http://localhost:8088/api/v1/orders/pay \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"order_id": 1,
"pay_method": "wechat",
"amount": 229
}'# 支付宝自动场景(推荐:优先当面付,失败回退网页支付)
curl -X POST http://localhost:8088/api/v1/payments/online/create \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"order_id": 1,
"channel": "alipay",
"scene": "auto"
}'
# 支付宝当面付(返回二维码链接 qr_code)
curl -X POST http://localhost:8088/api/v1/payments/online/create \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"order_id": 1,
"channel": "alipay",
"scene": "f2f"
}'
# 支付宝网页支付(返回 pay_url)
curl -X POST http://localhost:8088/api/v1/payments/online/create \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"order_id": 1,
"channel": "alipay",
"scene": "page"
}'
# 微信 Native 扫码支付(返回二维码链接 qr_code)
curl -X POST http://localhost:8088/api/v1/payments/online/create \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"order_id": 1,
"channel": "wechat",
"scene": "native"
}'
# 同一订单一键生成“支付宝 + 微信”双码
curl -X POST http://localhost:8088/api/v1/payments/online/create-dual-qr \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"order_id": 1,
"alipay_scene": "auto"
}'
# 查询在线支付状态(前端可轮询)
curl "http://localhost:8088/api/v1/payments/online/status?payment_no=QLON260220123456" \
-H "Authorization: Bearer $TOKEN"说明:
- 支付宝支持
auto/f2f/page/wap。 - 微信支持
native/jsapi/h5,jsapi需额外传openid。 - 创建在线支付后返回
cashier_url(例如:/pay/?ticket=...),可直接用于前台支付页展示订单号、金额、二维码与实时状态。 - 平台回调地址:
- 支付宝:
POST /api/v1/payments/alipay/notify - 微信:
POST /api/v1/payments/wechat/notify
- 支付宝:
# 主动向网关查询并同步(若已支付会自动入账)
curl -X POST http://localhost:8088/api/v1/payments/online/query \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"payment_no": "QLON260220123456"
}'
# 关闭未支付单(释放二维码)
curl -X POST http://localhost:8088/api/v1/payments/online/close \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"payment_no": "QLON260220123456"
}'
# 发起退款(refund_amount 不传则默认全额可退)
curl -X POST http://localhost:8088/api/v1/payments/online/refund \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"payment_no": "QLON260220123456",
"refund_amount": 100,
"reason": "客户临时取消项目"
}'
# 查看退款记录
curl "http://localhost:8088/api/v1/payments/online/refunds?payment_no=QLON260220123456" \
-H "Authorization: Bearer $TOKEN"说明:
- 退款会同步回冲订单
paid_amount、订单状态和客户累计消费。 - 微信退款要求已配置双向证书路径。
# 新增提成规则
curl -X POST http://localhost:8088/api/v1/commission/rules \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"rule_name": "服务项目默认10%",
"target_type": "service",
"rate_percent": 10,
"enabled": 1
}'
# 查看员工业绩
curl "http://localhost:8088/api/v1/performance/staff?date_from=2026-02-01&date_to=2026-02-28&store_id=1" \
-H "Authorization: Bearer $TOKEN"curl "http://localhost:8088/api/v1/reports/store-daily?date_from=2026-02-01&date_to=2026-02-28&store_id=1" \
-H "Authorization: Bearer $TOKEN"
curl "http://localhost:8088/api/v1/reports/customer-repurchase?date_from=2025-01-01&date_to=2026-02-28&store_id=1&min_orders=2" \
-H "Authorization: Bearer $TOKEN"# 按客户编号/手机号/卡号检索
curl "http://localhost:8088/api/v1/admin/customers/search?keyword=13800000000" \
-H "Authorization: Bearer $TOKEN"
# 手工调整会员卡(set_remaining 或 delta_sessions)
curl -X POST http://localhost:8088/api/v1/admin/member-cards/adjust \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"card_no": "QLMC2602201234",
"customer_mobile": "13800000000",
"mode": "delta_sessions",
"value": 2,
"note": "门店前台手工补次"
}'
# 手工补录消费(可绑定 appointment_id)
curl -X POST http://localhost:8088/api/v1/admin/member-cards/manual-consume \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"card_no": "QLMC2602201234",
"consume_sessions": 1,
"appointment_id": 1,
"note": "客户到店线下核销补录"
}'
# 修正已有预约消费记录
curl -X POST http://localhost:8088/api/v1/admin/appointment-consumes/adjust \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"appointment_id": 1,
"consume_sessions": 2,
"note": "原登记次数有误,后台修正"
}'说明:以上接口仅 manager/admin 可调用,所有动作会写入 qiling_member_card_logs 与 qiling_audit_logs。
curl -X POST http://localhost:8088/api/v1/admin/customers/onboard \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer": {
"name": "张女士",
"mobile": "13800000000",
"store_id": 1,
"source_channel": "门店自然到访",
"skin_type": "干性",
"notes": "对香精敏感"
},
"gift_balance": 200,
"gift_member_cards": [
{
"package_id": 1,
"total_sessions": 3,
"valid_days": 180,
"note": "新客体验赠卡"
}
],
"gift_coupons": [
{
"coupon_name": "到店立减券",
"coupon_type": "cash",
"face_value": 50,
"min_spend": 199,
"count": 2,
"expire_at": "2026-12-31 23:59:59"
}
]
}'curl -X POST http://localhost:8088/api/v1/admin/customers/consume-record \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer_mobile": "13800000000",
"store_id": 1,
"consume_amount": 399,
"deduct_balance_amount": 100,
"coupon_usages": [
{"coupon_code": "QLCP2602201234", "use_count": 1}
],
"member_card_usages": [
{"card_no": "QLMC2602201234", "consume_sessions": 1}
],
"note": "后台代客结算"
}'curl -X POST http://localhost:8088/api/v1/admin/customers/consume-record-adjust \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"consume_no": "QLCR2602201234",
"consume_amount": 299,
"deduct_balance_amount": 80,
"deduct_coupon_amount": 30,
"deduct_member_card_sessions": 1,
"note": "后台纠偏:原消费金额录入有误"
}'# 模式1:增减(delta)
curl -X POST http://localhost:8088/api/v1/admin/customers/wallet-adjust \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer_mobile": "13800000000",
"mode": "delta",
"change_type": "deduct",
"amount": 50,
"note": "客户线下补差价"
}'
# 模式2:直接改成指定余额(set_balance)
curl -X POST http://localhost:8088/api/v1/admin/customers/wallet-adjust \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer_no": "QLC2602201234",
"mode": "set_balance",
"amount": 300,
"note": "后台纠偏:余额修正"
}'# 发新券(grant)
curl -X POST http://localhost:8088/api/v1/admin/customers/coupon-adjust \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer_mobile": "13800000000",
"mode": "grant",
"coupon_name": "护理加赠券",
"coupon_type": "cash",
"face_value": 30,
"min_spend": 199,
"count": 2,
"expire_at": "2026-12-31 23:59:59",
"note": "老客回访补券"
}'
# 改已有券剩余次数(set_remaining / delta_count)
curl -X POST http://localhost:8088/api/v1/admin/customers/coupon-adjust \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer_mobile": "13800000000",
"mode": "delta_count",
"coupon_code": "QLCP260220123456",
"delta_count": -1,
"note": "后台代客核销"
}'说明:以上管理员接口会写入审计日志;其中余额调整写入 qiling_wallet_logs,优惠券调整写入 qiling_coupon_logs,会员卡相关写入 qiling_member_card_logs。
# 新增/更新会员等级
curl -X POST http://localhost:8088/api/v1/customer-grades \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"grade_name": "金卡",
"threshold_points": 1000,
"discount_rate": 95,
"enabled": 1
}'
# 手工调整积分
curl -X POST http://localhost:8088/api/v1/customer-points/change \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer_mobile": "13800000000",
"delta_points": 100,
"change_type": "manual_adjust",
"note": "活动补积分"
}'# 配置开门礼(建档触发)
curl -X POST http://localhost:8088/api/v1/open-gifts \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"trigger_type": "onboard",
"gift_name": "新客建档礼",
"enabled": 1,
"items": [
{"item_type": "points", "points_value": 200},
{"item_type": "coupon", "coupon_name": "新客到店券", "coupon_type": "cash", "face_value": 50, "min_spend": 199, "remain_count": 1, "expire_days": 30}
]
}'
# 手工触发开门礼
curl -X POST http://localhost:8088/api/v1/open-gifts/trigger \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"trigger_type": "manual",
"customer_mobile": "13800000000",
"store_id": 1
}'# 创建券包
curl -X POST http://localhost:8088/api/v1/coupon-groups \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"group_name": "38节到店券包",
"coupon_name": "到店立减30",
"coupon_type": "cash",
"face_value": 30,
"min_spend": 199,
"per_user_limit": 1,
"total_limit": 500,
"expire_days": 20
}'
# 批量发放(按手机号)
curl -X POST http://localhost:8088/api/v1/coupon-groups/send \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"group_id": 1,
"customer_mobiles": ["13800000000", "13900000000"]
}'# 优惠券转赠
curl -X POST http://localhost:8088/api/v1/coupons/transfer \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"coupon_code": "QLCP260220123456",
"to_customer_mobile": "13900000000",
"note": "后台代客转赠"
}'
# 次卡转赠
curl -X POST http://localhost:8088/api/v1/member-cards/transfer \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"card_no": "QLMC2602201234",
"to_customer_mobile": "13900000000",
"note": "后台代客转赠"
}'# 配置打印机
curl -X POST http://localhost:8088/api/v1/printers \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"printer_name": "前台小票机",
"provider": "manual",
"enabled": 1
}'
# 派发待打印任务
curl -X POST http://localhost:8088/api/v1/print-jobs/dispatch \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"limit": 50
}'$payload = [
'wp_user_id' => $user->ID,
'username' => $user->user_login,
'email' => $user->user_email,
'display_name' => $user->display_name,
'roles' => $user->roles,
'meta' => [
'phone' => get_user_meta($user->ID, 'phone', true),
],
];
$body = wp_json_encode($payload);
$ts = (string) time();
$sign = hash_hmac('sha256', $ts . '.' . $body, '你的共享密钥');
wp_remote_post('http://你的服务器:8088/api/v1/wp/users/sync', [
'headers' => [
'Content-Type' => 'application/json',
'X-QILING-WP-SECRET' => '你的共享密钥',
'X-QILING-WP-TS' => $ts,
'X-QILING-WP-SIGN' => $sign,
],
'body' => $body,
'timeout' => 15,
]);用户端访问口令默认开启防暴力策略,可通过 .env 调整:
PORTAL_TOKEN_MAX_FAILED_ATTEMPTS:同一访问口令连续失败上限(默认8)PORTAL_TOKEN_LOCK_SECONDS:达到上限后的锁定秒数(默认900)PORTAL_TOKEN_RATE_LIMIT_WINDOW_SECONDS:速率统计窗口(默认60)PORTAL_TOKEN_RATE_LIMIT_MAX_REQUESTS:窗口内同 IP 最大请求数(默认30)
策略说明:
- 失败锁定按“访问口令”维度隔离,避免同出口 IP 用户互相影响。
- 速率限制按 IP 生效,用于防刷请求。
后台口令管理接口示例(需 Bearer Token):
# 管理员重置客户访问口令(会自动作废该客户已有激活口令)
curl -X POST http://localhost:8088/api/v1/customer-portal/tokens/reset \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer_mobile": "13900000000",
"new_token": "123456",
"expire_days": 365,
"note": "管理员代重置"
}'
# 查询当前锁定记录(可按客户筛选)
curl "http://localhost:8088/api/v1/customer-portal/guards?locked_only=1&limit=80" \
-H "Authorization: Bearer $TOKEN"
# 按客户解锁口令锁定
curl -X POST http://localhost:8088/api/v1/customer-portal/guards/unlock \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer_mobile": "13900000000"
}'可选兼容项:
CRON_ALLOW_QUERY_KEY=false(默认):关闭?key=传参,只允许请求头X-QILING-CRON-KEYWP_SYNC_REQUIRE_SIGNATURE=true(默认):要求 WP 同步请求必须带时间戳签名WP_SYNC_SIGNATURE_TTL_SECONDS=300:WP 同步签名有效期(秒)
public/入口与路由public/install.php网页安装向导src/核心代码sql/schema.sql表结构
- 认证登录(token)
- 门店管理 API
- 员工管理 API
- 客户档案 API(含标签)
- 服务项目 API
- 疗程套餐 API
- 会员次卡开卡/核销流水 API
- 开单收款与订单明细 API
- 在线支付(下单/回调/状态同步/关单/退款)
- 后台手工纠偏(按会员编号/手机号/卡号修改会员卡与消费记录)
- 管理员建档与代客操作(赠送余额/赠送次卡/赠送优惠券/后台消费扣减)
- 管理员手工调账(客户余额/优惠券发放与次数调整)
- 消费记录手工修正(支持按消费单号纠偏并同步累计消费)
- 预约排班 API(含员工时间冲突检测)
- 自动核销与自动回退(基于预约状态)
- 回访计划与回访任务中心(D+1/3/7 自动生成)
- 消息推送中心(钉钉/飞书群机器人、测试发送、到期回访通知、新预约通知、推送日志)
- 外部监控平台定时任务(URL 触发回访生成/推送)
- 提成规则 v1 与员工业绩统计 API
- 门店日报与客户复购报表 API
- 门店数据隔离 v1(按账号门店自动限制)
- 会员等级与积分(自动累积 + 手工调整 + 等级映射)
- 开门礼(建档/首单触发,支持积分与优惠券)
- 券包管理(批量发券,含每人限领与总量控制)
- 转赠中心(优惠券转赠、次卡转赠)
- 小票打印(打印机管理、打印任务、订单收款自动创建小票)
- WordPress 用户同步 API
- 审计日志表