Laravel场景下如何从关联表获取属性值生成患者账单
解决方案:Laravel患者账单费用关联与计算
一、模型关联配置
首先确保Pasien模型与Poli、Tindakan模型建立关联(假设pasien表通过poli_id、tindakan_id关联另外两张表的主键):
// app/Models/Pasien.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Pasien extends Model { // 关联科室表 public function poli() { return $this->belongsTo(Poli::class); } // 关联诊疗操作表 public function tindakan() { return $this->belongsTo(Tindakan::class); } }
二、控制器预加载关联数据
在查询患者数据时,预加载关联的科室和诊疗操作数据,避免N+1查询问题:
// app/Http/Controllers/PasienController.php namespace App\Http\Controllers; use App\Models\Pasien; use Illuminate\Http\Request; class PasienController extends Controller { public function index() { // 预加载关联数据 $pasiens = Pasien::with(['poli', 'tindakan'])->get(); return view('pasien.index', compact('pasiens')); } }
三、视图展示费用与计算总费用
在患者列表视图中,直接从关联模型获取费用,并实时计算总费用:
<!-- resources/views/pasien/index.blade.php --> <table class="table"> <thead> <tr> <th>Nama Pasien</th> <th>Departemen</th> <th>Harga Karcis</th> <th>Tindakan</th> <th>Harga Tindakan</th> <th>Total Biaya</th> </tr> </thead> <tbody> @foreach($pasiens as $pasien) <tr> <td>{{ $pasien->nama_pasien }}</td> <td>{{ $pasien->poli->inisial ?? '-' }}</td> <td>Rp. {{ number_format($pasien->poli->harga ?? 0, 0, ',', '.') }}</td> <td>{{ $pasien->tindakan->namatindak ?? '-' }}</td> <td>Rp. {{ number_format($pasien->tindakan->harga ?? 0, 0, ',', '.') }}</td> <!-- 实时计算总费用 --> <td>Rp. {{ number_format(($pasien->poli->harga ?? 0) + ($pasien->tindakan->harga ?? 0), 0, ',', '.') }}</td> </tr> @endforeach </tbody> </table>
四、可选:将费用持久化到pasien表
如果需要把费用存储到pasien表(而非实时读取),按以下步骤操作:
1. 添加字段迁移
创建迁移文件添加账单字段:
php artisan make:migration add_billing_fields_to_pasiens_table
编辑迁移文件:
// database/migrations/xxxx_xx_xx_add_billing_fields_to_pasiens_table.php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up() { Schema::table('pasiens', function (Blueprint $table) { $table->integer('harga_karcis')->nullable(); $table->integer('harga_tindakan')->nullable(); $table->integer('total_biaya')->nullable(); }); } public function down() { Schema::table('pasiens', function (Blueprint $table) { $table->dropColumn(['harga_karcis', 'harga_tindakan', 'total_biaya']); }); } };
执行迁移:
php artisan migrate
2. 自动填充费用(模型事件)
在Pasien模型中添加事件监听,保存/更新时自动同步费用:
// app/Models/Pasien.php protected static function boot() { parent::boot(); // 新增患者时填充费用 static::creating(function ($pasien) { $this->syncBilling($pasien); }); // 更新患者时同步费用 static::updating(function ($pasien) { $this->syncBilling($pasien); }); } // 封装同步逻辑 private static function syncBilling($pasien) { $poli = Poli::find($pasien->poli_id); $tindakan = Tindakan::find($pasien->tindakan_id); $pasien->harga_karcis = $poli?->harga ?? 0; $pasien->harga_tindakan = $tindakan?->harga ?? 0; $pasien->total_biaya = ($poli?->harga ?? 0) + ($tindakan?->harga ?? 0); }
3. 批量更新现有患者数据
创建Artisan命令批量更新历史数据:
php artisan make:command UpdatePasienBilling
编辑命令文件:
// app/Console/Commands/UpdatePasienBilling.php namespace App\Console\Commands; use Illuminate\Console\Command; use App\Models\Pasien; class UpdatePasienBilling extends Command { protected $signature = 'pasien:update-billing'; protected $description = '批量更新所有患者的账单费用'; public function handle() { $count = 0; Pasien::chunk(100, function ($pasiens) use (&$count) { foreach ($pasiens as $pasien) { $poli = $pasien->poli; $tindakan = $pasien->tindakan; if ($poli && $tindakan) { $pasien->harga_karcis = $poli->harga; $pasien->harga_tindakan = $tindakan->harga; $pasien->total_biaya = $poli->harga + $tindakan->harga; $pasien->save(); $count++; } } }); $this->info("成功更新 {$count} 条患者账单数据"); } }
执行命令:
php artisan pasien:update-billing
内容的提问来源于stack exchange,提问作者arif
相关产品推荐
相关产品推荐

