1. 医美收费系统开发背景与需求分析
医美行业作为医疗健康领域的细分市场,近年来呈现爆发式增长态势。传统手工记账和通用收费软件已无法满足医美机构对项目组合计费、会员积分管理、分阶段收费等特色需求。我们团队最近为某连锁医美机构开发的这套系统,正是针对这些痛点设计的专业解决方案。
从技术选型角度看,Qt框架的跨平台特性完美适配医美机构多终端使用场景。机构前台需要Windows桌面端进行收银操作,咨询师需要Android平板展示价目,管理层则需通过Web后台查看报表。使用Qt只需维护一套C++核心代码,即可覆盖所有平台,大幅降低开发和维护成本。
2. 系统架构设计要点
2.1 模块化功能设计
系统采用经典的三层架构:
- 数据层:SQLite本地数据库+MySQL云端同步
- 业务层:C++实现核心计费逻辑
- 表现层:QML构建现代化UI
特别设计了智能计费引擎,支持以下特色功能:
- 项目组合优惠(如瘦脸针+玻尿酸套餐)
- 分阶段收费(术前30%、术中40%、术后30%)
- 医师分级定价(主任医师/普通医师差价)
- 会员积分抵现(1积分=1元,可叠加使用)
2.2 数据库关键表结构
sql复制-- 医疗服务项目表
CREATE TABLE medical_service (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
base_price REAL,
category_id INTEGER,
duration INTEGER -- 预计耗时(分钟)
);
-- 会员信息表
CREATE TABLE member (
id INTEGER PRIMARY KEY,
phone TEXT UNIQUE,
total_points INTEGER DEFAULT 0,
level INTEGER DEFAULT 1
);
-- 订单主表
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
member_id INTEGER,
doctor_id INTEGER,
total_amount REAL,
discount_amount REAL,
payment_status INTEGER DEFAULT 0
);
3. 核心功能实现细节
3.1 动态价格计算模块
价格计算需要考虑多重因素:
- 基础服务价格
- 医师等级加成
- 会员折扣
- 促销活动
- 积分抵扣
实现代码示例:
cpp复制double calculateFinalPrice(const ServiceItem &item,
const MemberInfo &member,
const Doctor &doctor) {
double price = item.basePrice;
// 医师等级加成
price *= doctor.priceFactor;
// 会员折扣
price *= member.discount;
// 促销活动
if (PromotionManager::hasPromotion(item.id)) {
price -= PromotionManager::getDiscountAmount(item.id);
}
// 积分抵扣(最高抵扣30%)
double maxDeduct = price * 0.3;
double actualDeduct = min(member.points, maxDeduct);
return price - actualDeduct;
}
3.2 小票打印功能
使用Qt的打印模块实现热敏小票打印,关键点包括:
- 使用QPrinter设置纸张尺寸(80mm宽度)
- 通过QPainter绘制小票内容
- 添加机构LOGO和防伪二维码
- 自动切纸指令发送
cpp复制void ReceiptPrinter::printReceipt(const Order &order) {
QPrinter printer(QPrinter::HighResolution);
printer.setPageSize(QPageSize(QPageSize::Custom));
printer.setPageSizeMM(QSizeF(80, 0)); // 宽度固定80mm
QPainter painter;
if (!painter.begin(&printer)) {
qWarning() << "Failed to initialize printer";
return;
}
// 绘制机构LOGO
painter.drawImage(QRect(10,10,60,60), QImage(":/images/logo.png"));
// 绘制订单明细
painter.setFont(QFont("Arial", 10));
painter.drawText(QRect(0,80,800,30), Qt::AlignCenter,
"消费单号:" + order.orderNo);
// ...其他绘制逻辑
// 添加切纸指令
printer.newPage();
}
4. 特殊业务场景处理
4.1 分期付款实现
医美项目常采用分期付款模式,系统需要:
- 记录每期应付款项
- 设置付款提醒
- 支持部分退款处理
数据库设计添加分期付款表:
sql复制CREATE TABLE installment (
id INTEGER PRIMARY KEY,
order_id INTEGER,
due_date TEXT,
amount REAL,
status INTEGER DEFAULT 0,
FOREIGN KEY(order_id) REFERENCES orders(id)
);
4.2 库存联动管理
耗材库存需要与收费项目联动:
- 玻尿酸等产品需要扣减库存
- 库存不足时提示预警
- 支持二级库房管理(总仓→分店)
实现库存检查逻辑:
cpp复制bool checkInventory(int itemId, int quantity) {
QSqlQuery query;
query.prepare("SELECT stock FROM inventory WHERE item_id=?");
query.addBindValue(itemId);
if (!query.exec() || !query.next()) {
return false;
}
int currentStock = query.value(0).toInt();
return currentStock >= quantity;
}
5. 开发中的难点与解决方案
5.1 高并发订单处理
促销活动时可能面临高并发下单,我们采用:
- SQLite WAL模式提升读写性能
- 关键操作添加事务锁
- 使用内存缓存热门商品库存
cpp复制void processOrder(const Order &order) {
QSqlDatabase::database().transaction();
try {
// 检查库存
if (!checkInventory(order.itemId, order.quantity)) {
throw std::runtime_error("库存不足");
}
// 扣减库存
deductInventory(order.itemId, order.quantity);
// 创建订单
createOrderRecord(order);
QSqlDatabase::database().commit();
} catch (...) {
QSqlDatabase::database().rollback();
throw;
}
}
5.2 跨平台UI适配
不同设备UI适配方案:
- 使用Qt的Screen类获取DPI参数
- 根据屏幕尺寸动态调整布局
- 关键控件使用QML的ResponsiveLayout
- 为Android平板优化触摸操作体验
qml复制// 响应式布局示例
GridLayout {
columns: Screen.desktopAvailableWidth > 1024 ? 3 : 2
Repeater {
model: serviceModel
delegate: ServiceItemCard {
Layout.fillWidth: true
Layout.minimumWidth: 200
}
}
}
6. 安全与合规设计要点
6.1 数据加密存储
- 患者隐私信息使用AES加密
- 数据库文件整体加密
- 操作日志完整记录
cpp复制QString encryptData(const QString &plainText) {
QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB);
QByteArray encodedText = encryption.encode(
plainText.toUtf8(),
QByteArray::fromHex(SECRET_KEY)
);
return QString::fromLatin1(encodedText.toBase64());
}
6.2 权限分级控制
RBAC权限模型设计:
- 收银员:基础收费功能
- 医师:治疗记录查询
- 店长:报表查看/折扣审批
- 管理员:系统配置
cpp复制bool checkPermission(int userId, PermissionType perm) {
QSqlQuery query;
query.prepare("SELECT 1 FROM role_permission rp "
"JOIN user_role ur ON rp.role_id=ur.role_id "
"WHERE ur.user_id=? AND rp.permission_id=?");
query.addBindValue(userId);
query.addBindValue(static_cast<int>(perm));
return query.exec() && query.next();
}
7. 部署与维护实践
7.1 自动更新机制
实现静默更新流程:
- 启动时检查更新
- 下载增量更新包
- 校验文件完整性
- 退出时自动替换文件
cpp复制void Updater::checkForUpdates() {
QNetworkAccessManager manager;
QEventLoop loop;
QNetworkReply *reply = manager.get(
QNetworkRequest(QUrl(UPDATE_CHECK_URL))
);
QObject::connect(reply, &QNetworkReply::finished, [&]() {
if (reply->error() == QNetworkReply::NoError) {
QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
processUpdateInfo(doc.object());
}
loop.quit();
});
loop.exec();
}
7.2 数据备份策略
- 每日凌晨自动本地备份
- 加密后上传云端
- 保留最近30天备份
- 支持一键恢复
bash复制# 备份脚本示例
#!/bin/bash
BACKUP_FILE="/backups/db_$(date +%Y%m%d).sqlite"
sqlite3 /data/clinic.db ".backup $BACKUP_FILE"
openssl enc -aes-256-cbc -salt -in $BACKUP_FILE -out ${BACKUP_FILE}.enc -pass pass:$SECRET
rclone copy ${BACKUP_FILE}.enc cloud:backups/
8. 实际应用效果
系统上线后客户反馈的关键改进点:
- 收费效率提升60%,平均结账时间从3分钟缩短到1分钟
- 套餐组合营销使客单价提升35%
- 会员复购率提高至42%
- 财务对账时间从2小时缩短到15分钟
特别受到好评的功能包括:
- 智能推荐套餐组合
- 会员生日自动折扣
- 医师业绩实时看板
- 移动端预约提醒
开发过程中我们积累了几个重要经验:首先是一定要深入业务场景,比如医美特有的"咨询师-医师-护士"多角色协作流程就需要特别设计;其次是性能优化要前置考虑,特别是促销活动时的并发压力;最后是必须重视数据安全,医疗相关数据的保护容不得半点马虎。