|
|
<?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);
|
|
|
}
|
|
|
}
|
|
|
}
|