Files
zyt/server/app/adminapi/logic/doctor/DoctorNoteLogic.php
T
2026-05-11 17:49:38 +08:00

206 lines
7.4 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace app\adminapi\logic\doctor;
use app\common\logic\BaseLogic;
use app\common\model\doctor\DoctorNote;
use app\common\service\FileService;
class DoctorNoteLogic extends BaseLogic
{
/**
* 按 diagnosis_id + 当天 find-or-create,追加 content / tongue_images / report_files
*/
public static function addOrAppend(array $params): bool
{
try {
$diagnosisId = (int) $params['diagnosis_id'];
$doctorId = (int) ($params['doctor_id'] ?? 0);
$today = date('Y-m-d');
$time = date('H:i');
$existing = DoctorNote::where('diagnosis_id', $diagnosisId)
->where('note_date', $today)
->whereNull('delete_time')
->find();
$newContent = trim($params['content'] ?? '');
$newImages = array_map([self::class, 'toRelativePath'], self::parseJsonArray($params['tongue_images'] ?? []));
$newReports = array_map([self::class, 'toRelativePath'], self::parseJsonArray($params['report_files'] ?? []));
if ($existing) {
$data = [];
if ($newContent !== '') {
$prev = trim($existing->content ?? '');
$line = "[{$time}] {$newContent}";
$data['content'] = $prev !== '' ? ($prev . "\n" . $line) : $line;
}
if (!empty($newImages)) {
$prev = self::parseJsonArray($existing->tongue_images);
$merged = array_values(array_unique(array_merge($prev, $newImages)));
$data['tongue_images'] = json_encode($merged, JSON_UNESCAPED_UNICODE);
}
if (!empty($newReports)) {
$prev = self::parseJsonArray($existing->report_files);
$merged = array_values(array_unique(array_merge($prev, $newReports)));
$data['report_files'] = json_encode($merged, JSON_UNESCAPED_UNICODE);
}
if (!empty($data)) {
$existing->save($data);
}
} else {
$content = $newContent !== '' ? "[{$time}] {$newContent}" : '';
DoctorNote::create([
'diagnosis_id' => $diagnosisId,
'doctor_id' => $doctorId,
'note_date' => $today,
'content' => $content,
'tongue_images' => !empty($newImages)
? json_encode($newImages, JSON_UNESCAPED_UNICODE)
: null,
'report_files' => !empty($newReports)
? json_encode($newReports, JSON_UNESCAPED_UNICODE)
: null,
]);
}
return true;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* 按 diagnosis_id 获取备注列表(note_date DESC
*/
public static function getByDiagnosis(int $diagnosisId, int $limit = 30): array
{
try {
if ($diagnosisId <= 0) {
return [];
}
$records = DoctorNote::where('diagnosis_id', $diagnosisId)
->whereNull('delete_time')
->order('note_date', 'desc')
->limit($limit)
->select()
->toArray();
foreach ($records as &$record) {
$record['tongue_images'] = array_map(function ($url) {
return empty($url) ? $url : FileService::getFileUrl($url);
}, self::parseJsonArray($record['tongue_images'] ?? []));
$record['report_files'] = array_map(function ($url) {
return empty($url) ? $url : FileService::getFileUrl($url);
}, self::parseJsonArray($record['report_files'] ?? []));
}
return $records;
} catch (\Exception $e) {
self::setError($e->getMessage());
return [];
}
}
/**
* 删除备注中的单张图片
*/
public static function deleteImage(int $noteId, string $imageType, string $imagePath): bool
{
try {
$note = DoctorNote::where('id', $noteId)->whereNull('delete_time')->find();
if (!$note) {
self::setError('记录不存在');
return false;
}
if (!in_array($imageType, ['tongue_images', 'report_files'])) {
self::setError('类型无效');
return false;
}
$images = self::parseJsonArray($note->$imageType);
// 统一转为相对路径再匹配
$targetPath = self::toRelativePath($imagePath);
$images = array_values(array_filter($images, fn($url) => self::toRelativePath($url) !== $targetPath));
$note->$imageType = empty($images) ? null : json_encode($images, JSON_UNESCAPED_UNICODE);
$note->save();
return true;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* 聚合某诊单所有备注中的图片(供 DiagnosisLogic::detail 使用)
*/
public static function getAggregatedImages(int $diagnosisId): array
{
$records = DoctorNote::where('diagnosis_id', $diagnosisId)
->whereNull('delete_time')
->select();
$tongueImages = [];
$reportFiles = [];
foreach ($records as $r) {
$tongueImages = array_merge($tongueImages, self::parseJsonArray($r->tongue_images));
$reportFiles = array_merge($reportFiles, self::parseJsonArray($r->report_files));
}
return [
'tongue_images' => array_map(
fn($u) => empty($u) ? $u : FileService::getFileUrl($u),
array_values(array_unique($tongueImages))
),
'report_files' => array_map(
fn($u) => empty($u) ? $u : FileService::getFileUrl($u),
array_values(array_unique($reportFiles))
),
];
}
/**
* 如果 URL 的域名是当前配置的存储域名则去掉,否则原样保留
*/
private static function toRelativePath(string $url): string
{
if (empty($url)) return $url;
if (stripos($url, 'http://') !== 0 && stripos($url, 'https://') !== 0) {
return $url;
}
// 获取当前存储域名
$domain = self::getStorageDomain();
if ($domain && stripos($url, rtrim($domain, '/')) === 0) {
$relative = substr($url, strlen(rtrim($domain, '/')));
return ltrim($relative, '/');
}
// 非当前存储域名,保留完整 URL
return $url;
}
private static function getStorageDomain(): string
{
$default = \app\common\service\ConfigService::get('storage', 'default', 'local');
if ($default === 'local') {
return request()->domain() . '/';
}
$storage = \app\common\service\ConfigService::get('storage', $default);
return $storage ? ($storage['domain'] ?? '') : '';
}
private static function parseJsonArray($value): array
{
if (is_array($value)) return $value;
if (is_string($value)) {
$decoded = json_decode($value, true);
return is_array($decoded) ? $decoded : [];
}
return [];
}
}