8.5 KiB
8.5 KiB
处方用量数据库实现完整指南
概述
为处方系统添加用量、单位和代煎字段的完整数据库实现。
1. 数据库迁移
执行SQL文件
文件: add_prescription_dosage_fields.sql
-- 添加处方用量相关字段
ALTER TABLE `zyt_tcm_prescription`
ADD COLUMN `dosage_amount` decimal(10,2) DEFAULT NULL COMMENT '用量数值' AFTER `prescription_type`,
ADD COLUMN `dosage_unit` varchar(10) NOT NULL DEFAULT '' COMMENT '用量单位(g/ml)' AFTER `dosage_amount`,
ADD COLUMN `need_decoction` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否代煎(0否1是,仅饮片)' AFTER `dosage_unit`;
执行方式
mysql -u用户名 -p数据库名 < add_prescription_dosage_fields.sql
字段说明
| 字段名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
dosage_amount |
decimal(10,2) | NULL | 用量数值,支持小数 |
dosage_unit |
varchar(10) | '' | 用量单位 (g/ml) |
need_decoction |
tinyint(1) | 0 | 是否代煎 (0=否, 1=是) |
2. 后端实现
2.1 模型层 (Model)
文件: server/app/common/model/tcm/Prescription.php
class Prescription extends BaseModel
{
// ... 其他配置
// 字段类型转换
protected $type = [
'dosage_amount' => 'float',
'need_decoction' => 'integer',
];
}
作用: 自动将数据库字段转换为正确的PHP类型。
2.2 业务逻辑层 (Logic)
文件: server/app/adminapi/logic/tcm/PrescriptionLogic.php
add() 方法 - 添加处方
$data = [
// ... 其他字段
'prescription_type' => $params['prescription_type'] ?? '浓缩水丸',
'dosage_amount' => isset($params['dosage_amount']) ? (float)$params['dosage_amount'] : null,
'dosage_unit' => $params['dosage_unit'] ?? '',
'need_decoction' => (int)($params['need_decoction'] ?? 0),
// ... 其他字段
];
edit() 方法 - 编辑处方
$data = [
// ... 其他字段
'prescription_type' => $params['prescription_type'] ?? $prescription->prescription_type,
'dosage_amount' => isset($params['dosage_amount']) ? (float)$params['dosage_amount'] : $prescription->dosage_amount,
'dosage_unit' => $params['dosage_unit'] ?? $prescription->dosage_unit,
'need_decoction' => isset($params['need_decoction']) ? (int)$params['need_decoction'] : (int)($prescription->need_decoction ?? 0),
// ... 其他字段
];
3. 前端实现
3.1 TypeScript 接口
文件: admin/src/components/tcm-prescription/index.vue
interface PrescriptionForm {
// ... 其他字段
prescription_type: string
dosage_amount: number | undefined
dosage_unit: string
need_decoction: boolean
// ... 其他字段
}
3.2 响应式数据
const formData = reactive<PrescriptionForm>({
// ... 其他字段
prescription_type: '浓缩水丸',
dosage_amount: 1,
dosage_unit: 'g',
need_decoction: false,
// ... 其他字段
})
3.3 自动切换逻辑
watch(() => formData.prescription_type, (newType) => {
if (newType === '浓缩水丸') {
formData.dosage_unit = 'g'
formData.dosage_amount = 1
formData.need_decoction = false
} else if (newType === '饮片') {
formData.dosage_unit = 'ml'
formData.dosage_amount = 50
} else {
formData.dosage_unit = 'g'
formData.dosage_amount = undefined
formData.need_decoction = false
}
})
4. 数据流转
4.1 保存流程
前端表单
↓
{
prescription_type: "浓缩水丸",
dosage_amount: 5,
dosage_unit: "g",
need_decoction: false
}
↓
后端 PrescriptionLogic::add()
↓
数据库 zyt_tcm_prescription
↓
dosage_amount: 5.00
dosage_unit: "g"
need_decoction: 0
4.2 读取流程
数据库查询
↓
Prescription Model (类型转换)
↓
{
dosage_amount: 5.0, // float
dosage_unit: "g", // string
need_decoction: 0 // int
}
↓
前端接收
↓
{
dosage_amount: 5,
dosage_unit: "g",
need_decoction: false
}
5. 数据示例
5.1 浓缩水丸处方
{
"prescription_type": "浓缩水丸",
"dosage_amount": 5.00,
"dosage_unit": "g",
"need_decoction": 0
}
5.2 饮片处方(代煎)
{
"prescription_type": "饮片",
"dosage_amount": 150.00,
"dosage_unit": "ml",
"need_decoction": 1
}
5.3 颗粒处方
{
"prescription_type": "颗粒",
"dosage_amount": 15.50,
"dosage_unit": "g",
"need_decoction": 0
}
6. 部署步骤
步骤 1: 备份数据库
mysqldump -u用户名 -p数据库名 > backup_$(date +%Y%m%d_%H%M%S).sql
步骤 2: 执行数据库迁移
mysql -u用户名 -p数据库名 < add_prescription_dosage_fields.sql
步骤 3: 验证字段添加
SHOW COLUMNS FROM `zyt_tcm_prescription` LIKE 'dosage%';
SHOW COLUMNS FROM `zyt_tcm_prescription` LIKE 'need_decoction';
步骤 4: 部署后端代码
# 上传修改的文件
- server/app/common/model/tcm/Prescription.php
- server/app/adminapi/logic/tcm/PrescriptionLogic.php
步骤 5: 部署前端代码
# 构建前端
cd admin
npm run build
# 上传构建产物
# 上传 dist/ 目录到服务器
步骤 6: 清除缓存(如需要)
cd server
php think clear
步骤 7: 测试功能
- 创建新处方,选择不同类型
- 验证用量字段正确保存
- 编辑处方,验证数据正确加载
- 查看处方详情,验证显示正确
7. 数据验证
7.1 前端验证
// 浓缩水丸:1-10g
if (formData.prescription_type === '浓缩水丸') {
if (formData.dosage_amount < 1 || formData.dosage_amount > 10) {
// 错误提示
}
}
// 饮片:50-250ml,步进50
if (formData.prescription_type === '饮片') {
if (formData.dosage_amount % 50 !== 0) {
// 错误提示
}
}
7.2 后端验证(建议添加)
// 在 PrescriptionLogic::add() 中添加
if ($params['prescription_type'] === '浓缩水丸') {
$amount = (float)($params['dosage_amount'] ?? 0);
if ($amount < 1 || $amount > 10) {
self::setError('浓缩水丸用量必须在1-10g之间');
return null;
}
}
if ($params['prescription_type'] === '饮片') {
$amount = (float)($params['dosage_amount'] ?? 0);
if ($amount < 50 || $amount > 250 || $amount % 50 !== 0) {
self::setError('饮片用量必须为50-250ml,且为50的倍数');
return null;
}
}
8. 常见问题
Q1: 字段已存在错误
ERROR 1060 (42S21): Duplicate column name 'dosage_amount'
解决: 字段已存在,跳过此步骤或先删除字段再添加。
Q2: 旧数据如何处理?
方案: 旧数据的 dosage_amount 为 NULL,前端显示为空,不影响功能。
Q3: 如何批量更新旧数据?
-- 为浓缩水丸类型设置默认用量
UPDATE `zyt_tcm_prescription`
SET
`dosage_amount` = 1,
`dosage_unit` = 'g'
WHERE `prescription_type` = '浓缩水丸'
AND `dosage_amount` IS NULL;
-- 为饮片类型设置默认用量
UPDATE `zyt_tcm_prescription`
SET
`dosage_amount` = 50,
`dosage_unit` = 'ml'
WHERE `prescription_type` = '饮片'
AND `dosage_amount` IS NULL;
9. 回滚方案
如果需要回滚,执行以下SQL:
-- 删除添加的字段
ALTER TABLE `zyt_tcm_prescription`
DROP COLUMN `dosage_amount`,
DROP COLUMN `dosage_unit`,
DROP COLUMN `need_decoction`;
10. 相关文件清单
数据库
add_prescription_dosage_fields.sql- 数据库迁移文件
后端
server/app/common/model/tcm/Prescription.php- 处方模型server/app/adminapi/logic/tcm/PrescriptionLogic.php- 处方业务逻辑
前端
admin/src/components/tcm-prescription/index.vue- 处方组件
文档
PRESCRIPTION_DOSAGE_FEATURE.md- 功能说明文档PRESCRIPTION_DOSAGE_DATABASE_IMPLEMENTATION.md- 本文档
11. 测试清单
- 数据库字段添加成功
- 创建浓缩水丸处方,用量1-10g
- 创建饮片处方,用量50-250ml
- 饮片处方代煎选项正常
- 编辑处方,数据正确加载
- 切换处方类型,用量自动调整
- 保存处方,数据正确存储
- 查看处方详情,显示正确
- 旧数据兼容性测试
总结
此实现完整覆盖了从数据库到前端的所有层次:
- ✅ 数据库字段添加
- ✅ 模型层类型转换
- ✅ 业务逻辑层数据处理
- ✅ 前端表单交互
- ✅ 自动切换逻辑
- ✅ 数据验证
所有代码已实现,只需执行数据库迁移即可使用!