Files
zyt/PRESCRIPTION_DOSAGE_DATABASE_IMPLEMENTATION.md
T
2026-04-15 16:31:25 +08:00

8.5 KiB
Raw Blame History

处方用量数据库实现完整指南

概述

为处方系统添加用量、单位和代煎字段的完整数据库实现。

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: 测试功能

  1. 创建新处方,选择不同类型
  2. 验证用量字段正确保存
  3. 编辑处方,验证数据正确加载
  4. 查看处方详情,验证显示正确

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
  • 饮片处方代煎选项正常
  • 编辑处方,数据正确加载
  • 切换处方类型,用量自动调整
  • 保存处方,数据正确存储
  • 查看处方详情,显示正确
  • 旧数据兼容性测试

总结

此实现完整覆盖了从数据库到前端的所有层次:

  1. 数据库字段添加
  2. 模型层类型转换
  3. 业务逻辑层数据处理
  4. 前端表单交互
  5. 自动切换逻辑
  6. 数据验证

所有代码已实现,只需执行数据库迁移即可使用!