You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

432 lines
15 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers\API\Admin;
use App\Http\Controllers\Controller;
use App\Services\PrintTemplateService;
use App\Lib\Rs;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
class PrintTemplateController extends Controller
{
private PrintTemplateService $printTemplateService;
public function __construct(PrintTemplateService $printTemplateService)
{
$this->printTemplateService = $printTemplateService;
}
/**
* 获取模板列表
*/
public function index(Request $request)
{
$templateType = $request->input('template_type');
$list = $this->printTemplateService->getTemplateList($templateType);
return Rs::success($list);
}
/**
* 获取默认模板
*/
public function getDefault(Request $request)
{
$templateType = $request->input('template_type', 'exam_application');
$template = $this->printTemplateService->getDefaultTemplate($templateType);
if (!$template) {
return Rs::error('未找到默认模板');
}
return Rs::success($template);
}
/**
* 获取单个模板根据ID
*/
public function show(Request $request)
{
$id = $request->input('id');
$templateCode = $request->input('template_code');
$template = null;
if ($id) {
$template = $this->printTemplateService->getTemplateById($id);
} elseif ($templateCode) {
$template = $this->printTemplateService->getTemplate($templateCode);
}
if (!$template) {
return Rs::error('模板不存在');
}
return Rs::success($template);
}
/**
* 创建模板
*/
public function store(Request $request)
{
$validated = $request->validate([
'template_code' => 'required|string|max:50|unique:print_templates,template_code',
'template_name' => 'required|string|max:100',
'template_type' => 'required|string|max:30',
'html_template' => 'required|string',
'css_style' => 'nullable|string',
'page_settings' => 'nullable|array',
'example_json' => 'nullable|string',
'is_default' => 'nullable|boolean',
]);
// 如果设为默认,取消其他默认模板
if (!empty($validated['is_default'])) {
DB::table('print_templates')
->where('template_type', $validated['template_type'])
->update(['is_default' => false]);
}
$templateId = $this->printTemplateService->saveTemplate($validated);
return Rs::success(['id' => $templateId], '模板创建成功');
}
/**
* 更新模板
*/
public function update(Request $request)
{
$validated = $request->validate([
'id' => 'required|integer',
'template_code' => 'required|string|max:50',
'template_name' => 'required|string|max:100',
'template_type' => 'required|string|max:30',
'html_template' => 'required|string',
'css_style' => 'nullable|string',
'page_settings' => 'nullable|array',
'example_json' => 'nullable|string',
'is_default' => 'nullable|boolean',
]);
// 如果设为默认,取消其他默认模板
if (!empty($validated['is_default'])) {
DB::table('print_templates')
->where('template_type', $validated['template_type'])
->where('id', '!=', $validated['id'])
->update(['is_default' => false]);
}
$this->printTemplateService->saveTemplate($validated);
return Rs::success([], '模板更新成功');
}
/**
* 设为默认模板
*/
public function setDefault(Request $request)
{
$id = $request->input('id');
$template = DB::table('print_templates')->where('id', $id)->first();
if (!$template) {
return Rs::error('模板不存在');
}
// 取消其他同类型模板的默认状态
DB::table('print_templates')
->where('template_type', $template->template_type)
->where('id', '!=', $id)
->update(['is_default' => false]);
// 设为默认
DB::table('print_templates')->where('id', $id)->update(['is_default' => true]);
return Rs::success([], '已设为默认模板');
}
/**
* 删除模板(软删除)
*/
public function destroy(Request $request)
{
$id = $request->input('id');
DB::table('print_templates')->where('id', $id)->update(['status' => false]);
return Rs::success([], '模板已删除');
}
/**
* 验证模板语法
*/
public function validate(Request $request)
{
$htmlTemplate = $request->input('html_template');
$result = $this->printTemplateService->validateTemplate($htmlTemplate);
if ($result['valid']) {
return Rs::success([], '模板语法正确');
}
return Rs::error($result['message'] ?? '模板语法错误');
}
/**
* 渲染 HTML预览
*/
public function render(Request $request)
{
$templateCode = $request->input('template_code');
$templateType = $request->input('template_type');
$data = $request->input('data', []);
// 如果传入 template_type使用默认模板
if ($templateType && !$templateCode) {
$defaultTemplate = $this->printTemplateService->getDefaultTemplate($templateType);
if (!$defaultTemplate) {
return Rs::error('未找到默认模板');
}
$templateCode = $defaultTemplate->template_code;
}
if (!$templateCode) {
return Rs::error('请指定 template_code 或 template_type');
}
try {
$html = $this->printTemplateService->renderTemplate($templateCode, $data);
return response($html)->header('Content-Type', 'text/html; charset=utf-8');
} catch (\Exception $e) {
$message = mb_convert_encoding($e->getMessage(), 'UTF-8', 'UTF-8,GBK,GB2312');
return Rs::error($message);
}
}
/**
* 生成 PDF
*/
public function pdf(Request $request)
{
$templateCode = $request->input('template_code');
$data = $request->input('data', []);
$download = $request->input('download', false);
$filename = $request->input('filename', 'document.pdf');
try {
$pdf = $this->printTemplateService->generatePDF($templateCode, $data);
if ($download) {
return $pdf->download($filename);
}
return $pdf->inline($filename);
} catch (\Exception $e) {
// 确保错误消息是有效的 UTF-8
$message = mb_convert_encoding($e->getMessage(), 'UTF-8', 'UTF-8,GBK,GB2312');
return response()->json([
'success' => false,
'message' => $message,
'code' => 500,
'data' => []
], 500)->setEncodingOptions(JSON_UNESCAPED_UNICODE);
}
}
/**
* 打印检查申请单(业务数据接口 - 准备数据)
*/
public function getExamApplicationData(Request $request)
{
try {
$applicationIds = $request->input('application_ids');
// 获取检查申请单数据(只需要申请单信息,不需要所有预约记录)
$applications = DB::table('exam_application as ea')
->whereIn('ea.id', $applicationIds)
->select([
'ea.id',
'ea.examination_item_name',
'ea.examination_department_name',
'ea.payment_status',
'ea.status',
'ea.apply_time',
'ea.patient_name',
'ea.patient_gender',
'ea.patient_age',
'ea.patient_phone',
'ea.patient_type',
'ea.inpatient_id',
'ea.outpatient_id',
'ea.ward_name',
'ea.bed_name'
])
->get();
if ($applications->isEmpty()) {
return Rs::error('未找到检查申请单');
}
// 获取第一个申请单信息
$firstApp = $applications[0];
// 获取该申请单最新的一条预约记录(如果有)
$latestAppointment = DB::table('exam_appointment as a')
->leftJoin('department_resource as dr', 'a.department_resource_id', '=', 'dr.id')
->where('a.exam_application_id', $firstApp->id)
->orderBy('a.created_at', 'desc')
->select(['a.appointment_time', 'dr.cancel_reason_required'])
->first();
// 计算星期
$weekdayLabel = '';
if (!empty($latestAppointment->appointment_time)) {
$weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
$weekdayLabel = $weekDays[date('w', strtotime($latestAppointment->appointment_time))];
}
// 患者类型名称
$patientTypeName = '';
switch ($firstApp->patient_type) {
case 1:
$patientTypeName = '门诊患者';
break;
case 2:
$patientTypeName = '住院患者';
break;
case 3:
$patientTypeName = '急诊患者';
break;
case 4:
$patientTypeName = '体检患者';
break;
default:
$patientTypeName = '未知';
}
// 准备模板数据
$data = [
'hospital_name' => '演示医院',
'barcode' => $firstApp->id,
// 患者信息(直接从 exam_application 表获取)
'patient_name' => $firstApp->patient_name ?? '',
'patient_gender' => $firstApp->patient_gender == 1 ? '男' : ($firstApp->patient_gender == 2 ? '女' : '未知'),
'patient_age' => $firstApp->patient_age ?? '',
'patient_type' => $firstApp->patient_type ?? 1,
'patient_type_name' => $patientTypeName,
// 住院/门诊号
'inpatient_id' => $firstApp->inpatient_id ?? '',
'outpatient_id' => $firstApp->outpatient_id ?? '',
// 病区/床号
'ward_name' => $firstApp->ward_name ?? '',
'bed_code' => $firstApp->bed_name ?? '',
// 联系方式
'patient_phone' => $firstApp->patient_phone ?? '',
// 检查项目
'examination_item_name' => $applications->pluck('examination_item_name')->implode('、'),
'examination_department_name' => $firstApp->examination_department_name ?? '',
// 预约信息(从最新预约记录获取)
'appointment_time' => $latestAppointment && $latestAppointment->appointment_time ? date('Y-m-d H:i', strtotime($latestAppointment->appointment_time)) : '',
'weekday_label' => $weekdayLabel,
'department_name' => $firstApp->examination_department_name ?? '',
'cancel_reason_required' => $latestAppointment->cancel_reason_required ?? 0,
// 申请时间
'entrust_date' => date('Y-m-d'),
'entrust_time' => date('H:i:s'),
];
return Rs::success($data);
} catch (\Exception $e) {
$message = mb_convert_encoding($e->getMessage(), 'UTF-8', 'UTF-8,GBK,GB2312');
return Rs::error($message);
}
}
/**
* 打印检查申请单(示例业务方法,返回 PDF
*/
public function printExamApplication(Request $request)
{
try {
$applicationIds = $request->input('application_ids');
$templateCode = $request->input('template_code');
$orderNo = $request->input('order_no', time());
// 获取检查申请单数据
$applications = DB::table('exam_application')
->whereIn('id', $applicationIds)
->get();
if ($applications->isEmpty()) {
return Rs::error('未找到检查申请单');
}
// 准备模板数据
$data = [
'hospital_name' => '某某医院',
'patient_name' => $applications[0]->patient_name ?? '',
'patient_id' => $applications[0]->patient_id ?? '',
'age' => $applications[0]->age ?? '',
'gender_text' => $applications[0]->gender == 1 ? '男' : ($applications[0]->gender == 2 ? '女' : '未知'),
'phone' => $applications[0]->phone ?? '',
'items' => $applications->map(function($app, $index) {
return [
'index' => $index + 1,
'item_name' => $app->item_name,
'item_code' => $app->item_code ?? '',
'remark' => $app->remark ?: '无',
];
})->toArray(),
'print_time' => now()->format('Y-m-d H:i:s'),
'operator' => '管理员',
'order_no' => $orderNo,
];
// 如果没有指定模板,使用默认模板
if (!$templateCode) {
$defaultTemplate = $this->printTemplateService->getDefaultTemplate('exam_application');
$templateCode = $defaultTemplate->template_code ?? 'exam_application_v1';
}
// 使用 LightnCandy 渲染模板
$html = $this->printTemplateService->renderTemplate($templateCode, $data);
// 使用 SnappyPdf 生成 PDF
$fileName = date('Ymd') . '/' . $orderNo . '.pdf';
$filePath = storage_path('app/public/CheckPdf/' . $fileName);
// 确保目录存在
$directory = dirname($filePath);
if (!file_exists($directory)) {
mkdir($directory, 0755, true);
}
// 生成 PDF
$this->printTemplateService->generatePDF($templateCode, $data, $filePath);
// 返回文件 URL
$fileUrl = Storage::url('CheckPdf/' . $fileName);
return Rs::success([
'file_url' => $fileUrl,
'file_path' => $filePath,
'order_no' => $orderNo
]);
} catch (\Exception $e) {
$message = mb_convert_encoding($e->getMessage(), 'UTF-8', 'UTF-8,GBK,GB2312');
return Rs::error($message);
}
}
}