简体中文说明(可直接放到 GitHub)。本项目是一个轻量级收银与称重管理系统,包含:商品管理、称重资料、临时条码生成、标签打印、以及手机扫码实时同步到收银端的功能。
- POS 收银台(扫码、购物车、结账)
- 商品管理:增删改查、批量/单品打印标签(40x30mm)
- 称重管理:称重商品资料维护与称重条码生成
- 打印集成:支持本地打印机(通过 dtpweb.js 打印 SDK)
- 手机扫码联动:手机端扫码实时推送到收银端(
api/sync_scan.php+mobile_scans表)
public/:前端页面(收银台、管理界面)scan/:移动扫码页面(standalone.html用于在手机上直接打开)api/:后端 PHP API(barcode.php,weighing.php,checkout.php,sync_scan.php,orders.php等)sql/setup.sql:数据库建表与初始化脚本
- 准备环境
- PHP 7.4+,MySQL
- 浏览器(收银端在桌面浏览器打开,扫码端在手机浏览器打开)
- 导入数据库
- 在 MySQL 中执行
sql/setup.sql:
# 使用命令行导入(示例)
mysql -u root -p < sql/setup.sql- 启动本地服务器(开发)
# 在项目根目录运行(示例端口 8000)
# 如果你的前端文件在 public/ 下并希望直接访问项目根,请按需修改 -t 参数
php -S 0.0.0.0:8000 -t y:\生活\Project\smkt\public- 访问页面
- 收银端(桌面):在电脑浏览器打开
http://<电脑局域网IP>:8000(例如http://192.168.31.5:8000) - 手机扫码端:打开
scan/standalone.html,或在手机浏览器访问http://<电脑局域网IP>:8000/scan/standalone.html
注意:若无法在手机上调用摄像头(因为没有 HTTPS),请参阅“部署与 HTTPS”节。
- 手机端
scan/standalone.html会将每次扫描的条码通过 POST 推送到:
POST http://<服务器IP>/api/sync_scan.php
body: { action: 'push', barcode: '...' }
- 收银端
public/js/app.js中实现了轮询sync_scan.php?action=pull的逻辑(每 1.2s 拉取一次),收到未处理的条码后会自动将其加入购物车并将该记录标记为已拾取。 - 同步表:
mobile_scans(字段:id, barcode, status, created_at)
api/barcode.php— 商品增删改查(action: create/read/update/delete)api/weighing.php— 称重资料管理与称重条码生成api/checkout.php— 结账、事务处理、销量入库api/sync_scan.php— 手机扫码中转(push / pull)api/orders.php— 交易历史查询
示例调用(pull):
POST /api/sync_scan.php
{ "action": "pull" }返回示例:
{ "status": "success", "data": [{ "id": 1, "barcode": "1234567890123" }] }- 前端使用
dtpweb.jsSDK 控制本地打印机(在收银机上需要安装打印助手)。 - 在收银台页面选择可用打印机后可进行单品或批量打印。若打印异常,先确认打印助手已启动且浏览器允许本地插件通信。
在内网环境中手机调用摄像头需要 HTTPS 或受信任的本地域名。常见解决方案:
-
临时快速:使用
ngrok或localtunnel暴露一个 HTTPS 地址(推荐测试时使用)。ngrok http 8000 -
长期内网信任:使用
mkcert+ 本地反向代理(Caddy / Nginx),为局域网域名签发受信任证书并让手机可解析该域名。
安全提示:ngrok 等会将服务暴露到公网,请在测试时注意接口鉴权,避免泄露敏感信息。
- 手机端摄像头不可用:通常是因为没有 HTTPS 或浏览器限制。若在内网无法申请证书,建议使用
scan/standalone.html并通过http://<局域网IP>直接访问(部分手机浏览器允许),或使用 ngrok。 - 出现重复扫码:扫码端设置了冷却时间(CD)以避免重复,若需要改短或加长,可修改
scan/standalone.html中的SCAN_CD参数(单位 ms)。
- 建议提交前运行基本检查,遇到问题请在 issue 中描述复现步骤与日志。
简要说明:这是一个基于 PHP + MySQL 的轻量级超市商品管理与收银后端示例,包含条码管理、结账、临时称重条码追溯与销售记录功能。
主要文件
- config/db.php : 数据库连接配置,使用 PDO 连接 MySQL,修改其中的 host/user/pass/db 以匹配你的环境。
- api/barcode.php : 条码 CRUD 接口(增/查/改/删),支持单条和批量查询(通过
barcodes数组),支持创建临时条码(is_temporary,库存设为 -1)。 - api/checkout.php : 结账接口,接收 JSON 列表,校验库存、生成订单号、记录销售与明细、处理临时条码(销毁并写入历史)。使用事务保证原子性并使用 FOR UPDATE 防止并发超卖。
- sql/setup.sql : 数据库初始化脚本,包含
barcodes,sales,sale_items,temporary_barcodes_history表定义。
数据库表(摘要)
barcodes: 主商品表,字段包含id, barcode, name, price, stock, is_temporary, created_at, updated_at。sales: 销售主表,字段包含id, order_no, employee_id, total_amount, payment_method, created_at。sale_items: 销售明细,记录每笔订单的商品快照,包含product_id, barcode, quantity, unit_price, subtotal。temporary_barcodes_history: 存储已失效的临时条码(用于追溯),包含generated_at, expired_at, sale_id。
API 使用示例(JSON)
- 条码创建(普通):
{ "action": "create", "data": { "barcode":"6901234567890","name":"可口可乐","price":3.5,"stock":50 } }- 条码创建(临时):
{ "action": "create", "data": { "barcode":"TEMP123","name":"称重西红柿","price":8.5,"is_temporary":true } }- 批量查询:
{ "action": "read", "data": { "barcodes": ["6901234567890","TEMP123"] } }- 结账(含员工 ID):
{
"employee_id": 101,
"payment_method": "wechat",
"items": [ { "barcode": "6901234567890", "quantity": 2 }, { "barcode": "TEMP123", "quantity": 1 } ]
}如何初始化数据库
- 在 MySQL 中运行
sql/setup.sql:
# 在命令行中(Windows PowerShell 示例)
mysql -u root -p < sql/setup.sql- 修改
[config/db.php](config/db.php)中的数据库连接配置。
已实现的关键特性
- 条码的增删改查(支持批量查询)
- 临时条码生命周期:在结账后自动失效并写入历史
- 事务级别的结算逻辑:库存校验、扣减、订单与明细写入要么全成功要么回滚
- 订单号生成与员工 ID 关联