Commit 7e1d9e3a by lujunyi

处方单打印

parent f618c846
......@@ -2,16 +2,201 @@
namespace App\Admin\Controllers;
use App\Models\PrescriptionModel;
use Dcat\Admin\Http\Controllers\AdminController;
use Dcat\Admin\Layout\Content;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Laravel\Facades\Image;
// 药店-处方打印
class PrescriptionPrintController extends AdminController
{
// 处方打印首页,显示输入框,可以搜索处方
public function index(Content $content): Content
{
// 加载处方打印页面
return $content->header('处方打印')
->description('')
->view('admin.prescription-print');
->description('根据处方编号搜索并打印处方')
->body(view('admin.prescription-print'));
}
/**
* 根据处方编号搜索处方并生成图片
*/
public function search()
{
$prescriptionNo = request('prescription_no');
if (empty($prescriptionNo)) {
return response()->json([
'status' => false,
'message' => '请输入处方编号',
]);
}
try {
// 获取处方信息
$prescription = PrescriptionModel::where('id', $prescriptionNo)->first();
if (! $prescription) {
return response()->json(['status' => false, 'message' => '未找到该处方']);
}
// 检查处方图片是否已经生成
if ($prescription->prescription_pic) {
return response()->json([
'status' => true,
'data' => [
'img_url' => Storage::url($prescription->prescription_pic),
],
]);
}
// 创建处方图片
// 处方背景图宽1653,高2339
$img = Image::read(public_path('static/images/chufangdan.jpg'));
// 医院
$imageWidth = 1653;
// 手动调整 X 坐标以居中
$centerX = $imageWidth / 2;
$img->text('江阴康恒诊所处方', $centerX, 110, function ($font) {
$font->filename(public_path('static/fonts/SimHei.ttf'));
$font->size(72);
$font->color('#000000');
$font->align('center'); // 使用 align('center') 以确保文本相对于 X 坐标居中
$font->valign('top'); // 确保文本垂直对齐方式
});
// 姓名
$img->text('周永福', 410, 260, function ($font) {
$font->filename(public_path('static/fonts/SimHei.ttf'));
$font->size(32);
$font->color('#000000');
});
// 性别
$img->text('男', 890, 260, function ($font) {
$font->filename(public_path('static/fonts/SimHei.ttf'));
$font->size(32);
$font->color('#000000');
});
// 年龄
$img->text('65岁', 1270, 260, function ($font) {
$font->filename(public_path('static/fonts/SimHei.ttf'));
$font->size(32);
$font->color('#000000');
});
// 日期
$img->text('2024-10-23', 1215, 330, function ($font) {
$font->filename(public_path('static/fonts/SimHei.ttf'));
$font->size(32);
$font->color('#000000');
});
// 诊断
$img->text('呼吸道感染', 330, 460, function ($font) {
$font->filename(public_path('static/fonts/SimHei.ttf'));
$font->size(32);
$font->color('#000000');
});
// 假设 $prescription->medicines 是一个包含药品信息的数组
// $medicines = $prescription->drug_info; // 每个元素包含 'name', 'spec', 'box', 'sig'
$medicines = [
[
'name' => '阿莫西林胶囊',
'spec' => '0.5g*20粒',
'box' => 2,
'sig' => '每日三次,每次两粒,饭后服用',
],
[
'name' => '布洛芬片',
'spec' => '0.2g*30片',
'box' => 1,
'sig' => '每日两次,每次一片,必要时服用',
],
[
'name' => '维生素C片',
'spec' => '100mg*100片',
'box' => 1,
'sig' => '每日一次,每次一片,早晨服用',
],
];
// 初始 Y 坐标
$yCoordinate = 650; // 根据需要调整初始 Y 坐标
foreach ($medicines as $medicine) {
// 打印药品名称、规格和盒数
$medicineText = "{$medicine['name']} {$medicine['spec']} {$medicine['box']}盒";
$img->text($medicineText, 550, $yCoordinate, function ($font) {
$font->filename(public_path('static/fonts/SimHei.ttf'));
$font->size(32);
$font->color('#000000');
$font->align('center');
});
// 增加 Y 坐标以打印下一行
$yCoordinate += 40; // 根据字体大小调整行间距
// 打印 sig 信息
$img->text('Sig: '.$medicine['sig'], 550, $yCoordinate, function ($font) {
$font->filename(public_path('static/fonts/SimHei.ttf'));
$font->size(32);
$font->color('#000000');
$font->align('center');
});
// 增加 Y 坐标以准备打印下一个药品
$yCoordinate += 60; // 根据字体大小调整行间距
}
// 打印两行空白
$yCoordinate += 30; // 空白行间距
$yCoordinate += 30; // 空白行间距
// 打印“以下空白”文字
$img->text('以下空白', 650, $yCoordinate, function ($font) {
$font->filename(public_path('static/fonts/SimHei.ttf'));
$font->size(32);
$font->color('#000000');
$font->align('center');
});
// 医师签名图片
if ($prescription->doctor_signed_pic) {
$doctorSignData = base64_decode($prescription->doctor_signed_pic);
$doctorSign = Image::read($doctorSignData);
$doctorSign->rotate(90);
$doctorSign->resize(150, 100);
$img->place($doctorSign, 'bottom-left', 400, 410);
}
// 药师签名图片
if ($prescription->pharmacist_signed_pic) {
$pharmacistSignData = base64_decode($prescription->pharmacist_signed_pic);
$pharmacistSign = Image::read($pharmacistSignData);
$pharmacistSign->rotate(90);
$pharmacistSign->resize(150, 100);
$img->place($pharmacistSign, 'bottom-left', 870, 410);
}
// 将图片保存到临时文件
$tempPath = storage_path('app/public').$prescriptionNo.'.jpg';
$img->save($tempPath);
// 上传到腾讯云
// \Storage::disk('cos')->putFileAs('prescriptions', $tempPath, $prescriptionNo.'.jpg');
// 删除临时文件
// unlink($tempPath);
// return response()->json([
// 'status' => true,
// 'data' => [
// 'img_url' => \Storage::disk('cos')->url($cosPath),
// ],
// ]);
} catch (\Exception $e) {
return response()->json([
'status' => false,
'message' => '处方生成失败:'.$e->getMessage(),
]);
}
}
}
......@@ -64,6 +64,8 @@
$router->resource('prescription-print', 'PrescriptionPrintController');
// 用法用量
$router->resource('dosage', 'DosageController');
// 搜索打印处方单
$router->get('prescription-search', 'PrescriptionPrintController@search');
});
/** 药店菜单-end **/
});
......@@ -11,6 +11,7 @@
"dcat/laravel-wherehasin": "^0.8.0",
"guanguans/dcat-login-captcha": "^1.1",
"guzzlehttp/guzzle": "^7.2",
"intervention/image-laravel": "^1.3",
"laravel/framework": "^10.10",
"laravel/helpers": "^1.6",
"laravel/sanctum": "^3.3",
......
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "44af1f9d3fa0d0609fd0179cfac581ec",
"content-hash": "7a80c242ca9ec5a49929d8f748ff10ea",
"packages": [
{
"name": "box/spout",
......@@ -1861,6 +1861,227 @@
"time": "2023-12-03T19:50:20+00:00"
},
{
"name": "intervention/gif",
"version": "4.2.0",
"source": {
"type": "git",
"url": "https://github.com/Intervention/gif.git",
"reference": "42c131a31b93c440ad49061b599fa218f06f93be"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/gif/zipball/42c131a31b93c440ad49061b599fa218f06f93be",
"reference": "42c131a31b93c440ad49061b599fa218f06f93be",
"shasum": ""
},
"require": {
"php": "^8.1"
},
"require-dev": {
"phpstan/phpstan": "^1",
"phpunit/phpunit": "^10.0",
"slevomat/coding-standard": "~8.0",
"squizlabs/php_codesniffer": "^3.8"
},
"type": "library",
"autoload": {
"psr-4": {
"Intervention\\Gif\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Oliver Vogel",
"email": "oliver@intervention.io",
"homepage": "https://intervention.io/"
}
],
"description": "Native PHP GIF Encoder/Decoder",
"homepage": "https://github.com/intervention/gif",
"keywords": [
"animation",
"gd",
"gif",
"image"
],
"support": {
"issues": "https://github.com/Intervention/gif/issues",
"source": "https://github.com/Intervention/gif/tree/4.2.0"
},
"funding": [
{
"url": "https://paypal.me/interventionio",
"type": "custom"
},
{
"url": "https://github.com/Intervention",
"type": "github"
},
{
"url": "https://ko-fi.com/interventionphp",
"type": "ko_fi"
}
],
"time": "2024-09-20T13:35:02+00:00"
},
{
"name": "intervention/image",
"version": "3.9.1",
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
"reference": "b496d1f6b9f812f96166623358dfcafb8c3b1683"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/image/zipball/b496d1f6b9f812f96166623358dfcafb8c3b1683",
"reference": "b496d1f6b9f812f96166623358dfcafb8c3b1683",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"intervention/gif": "^4.2",
"php": "^8.1"
},
"require-dev": {
"mockery/mockery": "^1.6",
"phpstan/phpstan": "^1",
"phpunit/phpunit": "^10.0",
"slevomat/coding-standard": "~8.0",
"squizlabs/php_codesniffer": "^3.8"
},
"suggest": {
"ext-exif": "Recommended to be able to read EXIF data properly."
},
"type": "library",
"autoload": {
"psr-4": {
"Intervention\\Image\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Oliver Vogel",
"email": "oliver@intervention.io",
"homepage": "https://intervention.io/"
}
],
"description": "PHP image manipulation",
"homepage": "https://image.intervention.io/",
"keywords": [
"gd",
"image",
"imagick",
"resize",
"thumbnail",
"watermark"
],
"support": {
"issues": "https://github.com/Intervention/image/issues",
"source": "https://github.com/Intervention/image/tree/3.9.1"
},
"funding": [
{
"url": "https://paypal.me/interventionio",
"type": "custom"
},
{
"url": "https://github.com/Intervention",
"type": "github"
},
{
"url": "https://ko-fi.com/interventionphp",
"type": "ko_fi"
}
],
"time": "2024-10-27T10:15:54+00:00"
},
{
"name": "intervention/image-laravel",
"version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/Intervention/image-laravel.git",
"reference": "24738a017d42a6fa8d9adabdbd69a2c19c5b0d30"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/image-laravel/zipball/24738a017d42a6fa8d9adabdbd69a2c19c5b0d30",
"reference": "24738a017d42a6fa8d9adabdbd69a2c19c5b0d30",
"shasum": ""
},
"require": {
"illuminate/support": "^8|^9|^10|^11",
"intervention/image": "^3.7",
"php": "^8.1"
},
"require-dev": {
"orchestra/testbench": "^8.18",
"phpunit/phpunit": "^10.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Intervention\\Image\\Laravel\\ServiceProvider"
],
"aliases": {
"Image": "Intervention\\Image\\Laravel\\Facades\\Image"
}
}
},
"autoload": {
"psr-4": {
"Intervention\\Image\\Laravel\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Oliver Vogel",
"email": "oliver@intervention.io",
"homepage": "https://intervention.io/"
}
],
"description": "Laravel Integration of Intervention Image",
"homepage": "https://image.intervention.io/",
"keywords": [
"gd",
"image",
"imagick",
"laravel",
"resize",
"thumbnail",
"watermark"
],
"support": {
"issues": "https://github.com/Intervention/image-laravel/issues",
"source": "https://github.com/Intervention/image-laravel/tree/1.3.0"
},
"funding": [
{
"url": "https://paypal.me/interventionio",
"type": "custom"
},
{
"url": "https://github.com/Intervention",
"type": "github"
}
],
"time": "2024-06-15T08:20:20+00:00"
},
{
"name": "laravel/framework",
"version": "v10.48.22",
"source": {
......
<?php
return [
/*
|--------------------------------------------------------------------------
| Image Driver
|--------------------------------------------------------------------------
|
| Intervention Image supports “GD Library” and “Imagick” to process images
| internally. Depending on your PHP setup, you can choose one of them.
|
| Included options:
| - \Intervention\Image\Drivers\Gd\Driver::class
| - \Intervention\Image\Drivers\Imagick\Driver::class
|
*/
'driver' => \Intervention\Image\Drivers\Gd\Driver::class,
/*
|--------------------------------------------------------------------------
| Configuration Options
|--------------------------------------------------------------------------
|
| These options control the behavior of Intervention Image.
|
| - "autoOrientation" controls whether an imported image should be
| automatically rotated according to any existing Exif data.
|
| - "decodeAnimation" decides whether a possibly animated image is
| decoded as such or whether the animation is discarded.
|
| - "blendingColor" Defines the default blending color.
*/
'options' => [
'autoOrientation' => true,
'decodeAnimation' => true,
'blendingColor' => 'ffffff',
]
];
......@@ -25,7 +25,7 @@ public function up()
$table->string('pre_packaged_food')->comment('仅销售预包装食品备案表');
$table->string('area', 64)->comment('地区');
$table->string('address', 128)->comment('详细地址');
$table->string('mobile', 11)->comment('药店管理员手机号');
$table->string('mobile', 11)->unique('uk_mobile')->comment('药店管理员手机号');
$table->string('business_hours', 32)->comment('营业时间');
$table->string('lng', 20)->nullable()->comment('经度');
$table->string('lat', 20)->nullable()->comment('纬度');
......
<!-- resources/views/admin/prescription-print.blade.php -->
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">处方单查询</h3>
<div class="search-form">
<div class="input-group mb-3">
<input type="text" class="form-control" id="prescription_no" placeholder="请输入处方编号">
<div class="input-group-append">
<button class="btn btn-primary" type="button" id="search-btn">
<i class="fa fa-search"></i> 搜索
</button>
</div>
</div>
<div class="box-body">
<form action="{{ admin_url('prescription/search') }}" method="get">
<div class="form-group">
<label for="prescription_code">处方单编码</label>
<input type="text" class="form-control" id="prescription_code" name="code" placeholder="请输入或扫描处方单编码">
</div>
<button type="submit" class="btn btn-primary">搜索</button>
</form>
</div>
<div class="prescription-preview" id="prescription-container" style="display:none">
<div class="text-center">
<img id="prescription-image" class="img-fluid" style="max-width:100%">
<div class="mt-3">
<button class="btn btn-success" id="download-btn">
<i class="fa fa-download"></i> 下载处方
</button>
<button class="btn btn-primary" id="print-btn">
<i class="fa fa-print"></i> 打印处方
</button>
</div>
</div>
</div>
<script>
Dcat.ready(function () {
console.log('文档加载完成');
// 初始化处方打印页面
const prescriptionHandler = new class {
constructor() {
console.log('初始化处方处理器');
this.init();
}
init() {
console.log('开始绑定事件');
// 绑定搜索事件
$('#prescription_no').on('keypress', (e) => {
if (e.which === 13) {
console.log('回车搜索触发');
this.search();
}
});
$('#search-btn').on('click', () => {
console.log('点击搜索按钮');
this.search();
});
$('#download-btn').on('click', () => this.download());
$('#print-btn').on('click', () => this.print());
console.log('事件绑定完成');
}
search() {
console.log('进入搜索方法');
let prescriptionNo = $('#prescription_no').val();
if (!prescriptionNo) {
Dcat.warning('请输入处方编号');
return;
}
console.log('开始发送请求,处方编号:', prescriptionNo);
Dcat.loading();
$.ajax({
url: "{{ admin_url('prescription-search') }}",
type: 'POST',
dataType: 'json',
data: {
prescription_no: prescriptionNo,
_token: '{{ csrf_token() }}'
},
success: (response) => {
console.log('请求成功:', response);
Dcat.loading(false);
if (response.status) {
$('#prescription-image').attr('src', response.data.img_url);
$('#download-btn').data('url', response.data.img_url);
$('#prescription-container').show();
} else {
Dcat.error(response.message || '获取处方失败');
}
},
error: (xhr) => {
console.error('请求失败:', xhr);
Dcat.loading(false);
Dcat.error('请求失败,请稍后重试');
}
});
}
// 下载处方
download() {
let url = $('#download-btn').data('url');
if (!url) {
Dcat.error('请先搜索处方');
return;
}
window.open(url, '_blank');
}
// 打印处方
print() {
let prescriptionNo = $('#prescription_no').val();
if (!prescriptionNo) {
Dcat.error('请先搜索处方');
return;
}
// 打开新的打印页面
let printUrl = '{{ admin_url('prescription-print/view') }}' + '?prescription_no=' + encodeURIComponent(prescriptionNo);
window.open(printUrl, '_blank');
}
}(); // 注意这里立即实例化类
});
</script>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment