更新
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
namespace app\adminapi\logic;
|
||||
|
||||
|
||||
use app\common\enum\FileEnum;
|
||||
use app\common\logic\BaseLogic;
|
||||
use app\common\model\file\File;
|
||||
use app\common\model\file\FileCate;
|
||||
@@ -36,7 +37,10 @@ class FileLogic extends BaseLogic
|
||||
*/
|
||||
public static function move($params)
|
||||
{
|
||||
$adminId = (int)(request()->adminId ?? 0);
|
||||
(new File())->whereIn('id', $params['ids'])
|
||||
->where('source', FileEnum::SOURCE_ADMIN)
|
||||
->where('source_id', $adminId)
|
||||
->update([
|
||||
'cid' => $params['cid'],
|
||||
'update_time' => time()
|
||||
@@ -51,7 +55,10 @@ class FileLogic extends BaseLogic
|
||||
*/
|
||||
public static function rename($params)
|
||||
{
|
||||
$adminId = (int)(request()->adminId ?? 0);
|
||||
(new File())->where('id', $params['id'])
|
||||
->where('source', FileEnum::SOURCE_ADMIN)
|
||||
->where('source_id', $adminId)
|
||||
->update([
|
||||
'name' => $params['name'],
|
||||
'update_time' => time()
|
||||
@@ -66,7 +73,15 @@ class FileLogic extends BaseLogic
|
||||
*/
|
||||
public static function delete($params)
|
||||
{
|
||||
$result = File::whereIn('id', $params['ids'])->select();
|
||||
$adminId = (int)(request()->adminId ?? 0);
|
||||
$result = File::whereIn('id', $params['ids'])
|
||||
->where('source', FileEnum::SOURCE_ADMIN)
|
||||
->where('source_id', $adminId)
|
||||
->select();
|
||||
$ids = $result->column('id');
|
||||
if (empty($ids)) {
|
||||
return;
|
||||
}
|
||||
$StorageDriver = new StorageDriver([
|
||||
'default' => ConfigService::get('storage', 'default', 'local'),
|
||||
'engine' => ConfigService::get('storage') ?? ['local'=>[]],
|
||||
@@ -74,7 +89,7 @@ class FileLogic extends BaseLogic
|
||||
foreach ($result as $item) {
|
||||
$StorageDriver->delete($item['uri']);
|
||||
}
|
||||
File::destroy($params['ids']);
|
||||
File::destroy($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,8 +138,12 @@ class FileLogic extends BaseLogic
|
||||
// 删除分类及子分类
|
||||
$cateModel->whereIn('id', $cateIds)->update(['delete_time' => time()]);
|
||||
|
||||
// 删除文件
|
||||
$fileIds = $fileModel->whereIn('cid', $cateIds)->column('id');
|
||||
// 删除文件(仅当前管理员在该分类下的素材)
|
||||
$adminId = (int)(request()->adminId ?? 0);
|
||||
$fileIds = $fileModel->whereIn('cid', $cateIds)
|
||||
->where('source', FileEnum::SOURCE_ADMIN)
|
||||
->where('source_id', $adminId)
|
||||
->column('id');
|
||||
|
||||
if (!empty($fileIds)) {
|
||||
self::delete(['ids' => $fileIds]);
|
||||
|
||||
@@ -591,6 +591,289 @@ class DiagnosisLogic extends BaseLogic
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有可能以 doctor_{id} 登录 IM 的后台账号(医生 role_id=1、医助 role_id=2),用于合并会话漫游记录
|
||||
*
|
||||
* @return array<int, string> 如 ['doctor_1','doctor_2']
|
||||
*/
|
||||
private static function collectAllDoctorImPeerAccounts(): array
|
||||
{
|
||||
try {
|
||||
$ids = \app\common\model\auth\Admin::alias('a')
|
||||
->join('admin_role ar', 'a.id = ar.admin_id')
|
||||
->whereIn('ar.role_id', [1, 2])
|
||||
->where('a.disable', 0)
|
||||
->group('a.id')
|
||||
->column('a.id');
|
||||
$accounts = [];
|
||||
foreach ($ids as $id) {
|
||||
$accounts[] = 'doctor_' . (int)$id;
|
||||
}
|
||||
|
||||
return array_values(array_unique($accounts));
|
||||
} catch (\Exception $e) {
|
||||
\think\facade\Log::error('collectAllDoctorImPeerAccounts: ' . $e->getMessage());
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 拉取与本诊单相关的腾讯云 IM 单聊记录(C2C:patient_{患者ID} 与 全部医生/医助账号 doctor_* 分别会话后合并)
|
||||
*/
|
||||
public static function getImChatMessagesForDiagnosis(int $diagnosisId)
|
||||
{
|
||||
try {
|
||||
$config = self::getTrtcConfig();
|
||||
if (!$config) {
|
||||
self::setError('请先配置腾讯云 TRTC / IM 参数');
|
||||
return false;
|
||||
}
|
||||
$diag = Diagnosis::where('id', $diagnosisId)->where('delete_time', null)->find();
|
||||
if (!$diag) {
|
||||
self::setError('诊单不存在');
|
||||
return false;
|
||||
}
|
||||
$patientId = (int)$diag['patient_id'];
|
||||
if ($patientId <= 0) {
|
||||
self::setError('诊单缺少患者信息');
|
||||
return false;
|
||||
}
|
||||
$patientImId = 'patient_' . $patientId;
|
||||
$doctorAccounts = self::collectAllDoctorImPeerAccounts();
|
||||
$assistantId = isset($diag['assistant_id']) ? (int)$diag['assistant_id'] : 0;
|
||||
if ($assistantId > 0) {
|
||||
$doctorAccounts[] = 'doctor_' . $assistantId;
|
||||
}
|
||||
$doctorAccounts = array_values(array_unique($doctorAccounts));
|
||||
if (empty($doctorAccounts)) {
|
||||
self::setError('未找到医生/医助角色账号,无法拉取 IM 记录');
|
||||
return false;
|
||||
}
|
||||
|
||||
$imService = new \app\common\service\TencentImService();
|
||||
$merged = [];
|
||||
foreach ($doctorAccounts as $docAccount) {
|
||||
$batch = self::pullAllRoamMessages($imService, $docAccount, $patientImId);
|
||||
foreach ($batch as $row) {
|
||||
$merged[] = $row;
|
||||
}
|
||||
}
|
||||
usort($merged, function ($a, $b) {
|
||||
return ($a['time'] ?? 0) <=> ($b['time'] ?? 0);
|
||||
});
|
||||
$seen = [];
|
||||
$unique = [];
|
||||
foreach ($merged as $row) {
|
||||
$k = $row['msg_id'] ?? '';
|
||||
if ($k !== '' && isset($seen[$k])) {
|
||||
continue;
|
||||
}
|
||||
if ($k !== '') {
|
||||
$seen[$k] = true;
|
||||
}
|
||||
$unique[] = $row;
|
||||
}
|
||||
|
||||
$unique = self::enrichImMessagesWithStaffNames($unique);
|
||||
|
||||
return [
|
||||
'lists' => $unique,
|
||||
'patient_im_id' => $patientImId,
|
||||
'patient_name' => $diag['patient_name'] ?? '',
|
||||
'doctor_accounts_queried' => $doctorAccounts,
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
self::setError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为 from_account = doctor_{id} 的消息补充后台姓名,便于前端区分不同医生
|
||||
*
|
||||
* @param array<int, array<string, mixed>> $rows
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private static function enrichImMessagesWithStaffNames(array $rows): array
|
||||
{
|
||||
$ids = [];
|
||||
foreach ($rows as $r) {
|
||||
$f = (string)($r['from_account'] ?? '');
|
||||
if (preg_match('/^doctor_(\d+)$/', $f, $m)) {
|
||||
$ids[] = (int)$m[1];
|
||||
}
|
||||
}
|
||||
$ids = array_unique($ids);
|
||||
if (empty($ids)) {
|
||||
return $rows;
|
||||
}
|
||||
$map = \app\common\model\auth\Admin::whereIn('id', $ids)->column('name', 'id');
|
||||
foreach ($rows as $k => $r) {
|
||||
$f = (string)($r['from_account'] ?? '');
|
||||
if (preg_match('/^doctor_(\d+)$/', $f, $m)) {
|
||||
$aid = (int)$m[1];
|
||||
$rows[$k]['from_staff_name'] = $map[$aid] ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private static function pullAllRoamMessages(\app\common\service\TencentImService $svc, string $operator, string $peer): array
|
||||
{
|
||||
$out = [];
|
||||
$lastKey = null;
|
||||
$lastTime = null;
|
||||
$guard = 0;
|
||||
do {
|
||||
$res = $svc->adminGetRoamMsg($operator, $peer, 100, 0, 4294967295, $lastKey, $lastTime);
|
||||
if (!$res['success']) {
|
||||
if (!empty($res['error'])) {
|
||||
\think\facade\Log::warning('IM漫游消息拉取失败', [
|
||||
'operator' => $operator,
|
||||
'peer' => $peer,
|
||||
'error' => $res['error'],
|
||||
'code' => $res['rawErrorCode'] ?? 0,
|
||||
]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
foreach ($res['msgList'] as $raw) {
|
||||
if (!is_array($raw)) {
|
||||
continue;
|
||||
}
|
||||
$out[] = self::normalizeTimMessage($raw);
|
||||
}
|
||||
$complete = (int)$res['complete'];
|
||||
if ($complete === 1) {
|
||||
break;
|
||||
}
|
||||
$lastKey = $res['lastMsgKey'];
|
||||
$lastTime = $res['lastMsgTime'];
|
||||
if ($lastKey === null || $lastKey === '') {
|
||||
break;
|
||||
}
|
||||
$guard++;
|
||||
if ($guard > 80) {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $raw
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private static function normalizeTimMessage(array $raw): array
|
||||
{
|
||||
$from = (string)($raw['From_Account'] ?? '');
|
||||
$to = (string)($raw['To_Account'] ?? '');
|
||||
$time = (int)($raw['MsgTimeStamp'] ?? $raw['MsgTime'] ?? 0);
|
||||
$seq = $raw['MsgSeq'] ?? '';
|
||||
$rand = $raw['MsgRandom'] ?? '';
|
||||
$msgId = $seq . '_' . $rand . '_' . $from;
|
||||
$isDoctor = strpos($from, 'doctor_') === 0;
|
||||
$parsed = self::parseTimMsgBody($raw['MsgBody'] ?? []);
|
||||
|
||||
return array_merge(
|
||||
[
|
||||
'msg_id' => $msgId,
|
||||
'from_account' => $from,
|
||||
'to_account' => $to,
|
||||
'time' => $time,
|
||||
'is_from_doctor' => $isDoctor,
|
||||
],
|
||||
$parsed
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $body
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private static function parseTimMsgBody($body): array
|
||||
{
|
||||
$out = [
|
||||
'msg_type' => 'other',
|
||||
'text' => '',
|
||||
'image_url' => '',
|
||||
'file_url' => '',
|
||||
'file_name' => '',
|
||||
'raw_elem_type' => '',
|
||||
];
|
||||
if (!is_array($body) || !$body) {
|
||||
return $out;
|
||||
}
|
||||
foreach ($body as $elem) {
|
||||
if (!is_array($elem)) {
|
||||
continue;
|
||||
}
|
||||
$type = (string)($elem['MsgType'] ?? '');
|
||||
$out['raw_elem_type'] = $type;
|
||||
$content = $elem['MsgContent'] ?? [];
|
||||
if (!is_array($content)) {
|
||||
$content = [];
|
||||
}
|
||||
switch ($type) {
|
||||
case 'TIMTextElem':
|
||||
$out['msg_type'] = 'text';
|
||||
$out['text'] = (string)($content['Text'] ?? '');
|
||||
return $out;
|
||||
case 'TIMImageElem':
|
||||
$out['msg_type'] = 'image';
|
||||
$arr = $content['ImageInfoArray'] ?? [];
|
||||
if (is_array($arr)) {
|
||||
foreach ($arr as $info) {
|
||||
if (is_array($info) && !empty($info['URL'])) {
|
||||
$out['image_url'] = (string)$info['URL'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
case 'TIMFileElem':
|
||||
$out['msg_type'] = 'file';
|
||||
$out['file_url'] = (string)($content['Url'] ?? '');
|
||||
$out['file_name'] = (string)($content['FileName'] ?? '');
|
||||
return $out;
|
||||
case 'TIMSoundElem':
|
||||
$out['msg_type'] = 'sound';
|
||||
$out['file_url'] = (string)($content['Url'] ?? '');
|
||||
return $out;
|
||||
case 'TIMVideoFileElem':
|
||||
$out['msg_type'] = 'video';
|
||||
$out['file_url'] = (string)($content['VideoUrl'] ?? '');
|
||||
return $out;
|
||||
case 'TIMVideoElem':
|
||||
$out['msg_type'] = 'video';
|
||||
$out['file_url'] = (string)($content['VideoUrl'] ?? '');
|
||||
return $out;
|
||||
case 'TIMLocationElem':
|
||||
$out['msg_type'] = 'location';
|
||||
$out['text'] = (string)($content['Desc'] ?? '');
|
||||
return $out;
|
||||
case 'TIMCustomElem':
|
||||
$out['msg_type'] = 'custom';
|
||||
$out['text'] = (string)($content['Data'] ?? '');
|
||||
return $out;
|
||||
case 'TIMFaceElem':
|
||||
$out['msg_type'] = 'face';
|
||||
$out['text'] = (string)($content['Index'] ?? '');
|
||||
return $out;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 发起通话
|
||||
@@ -685,6 +968,15 @@ class DiagnosisLogic extends BaseLogic
|
||||
$record['start_time_text'] = date('Y-m-d H:i:s', $record['start_time']);
|
||||
$record['end_time_text'] = $record['end_time'] ? date('Y-m-d H:i:s', $record['end_time']) : '';
|
||||
$record['duration_text'] = self::formatDuration($record['duration']);
|
||||
$urls = [];
|
||||
if (!empty($record['recording_urls'])) {
|
||||
$decoded = json_decode((string)$record['recording_urls'], true);
|
||||
if (is_array($decoded)) {
|
||||
$urls = $decoded;
|
||||
}
|
||||
}
|
||||
$record['recording_urls_list'] = $urls;
|
||||
$record['recording_status_text'] = self::recordingStatusText((int)($record['recording_status'] ?? 0));
|
||||
}
|
||||
|
||||
return $records;
|
||||
@@ -693,6 +985,58 @@ class DiagnosisLogic extends BaseLogic
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 将 TRTC 房间号写入当前诊单最近一次通话记录,便于云端录制回调按 room_id 关联
|
||||
*/
|
||||
public static function bindCallRoom(array $params): bool
|
||||
{
|
||||
try {
|
||||
$diagnosisId = (int)($params['diagnosis_id'] ?? 0);
|
||||
$roomId = trim((string)($params['room_id'] ?? ''));
|
||||
if ($diagnosisId <= 0 || $roomId === '') {
|
||||
self::setError('诊单ID或房间号不能为空');
|
||||
return false;
|
||||
}
|
||||
|
||||
$record = \app\common\model\tcm\CallRecord::where('diagnosis_id', $diagnosisId)
|
||||
->where('status', 1)
|
||||
->order('id', 'desc')
|
||||
->find();
|
||||
if (!$record) {
|
||||
$record = \app\common\model\tcm\CallRecord::where('diagnosis_id', $diagnosisId)
|
||||
->where('room_id', '')
|
||||
->order('id', 'desc')
|
||||
->find();
|
||||
}
|
||||
if (!$record) {
|
||||
self::setError('未找到可绑定的通话记录');
|
||||
return false;
|
||||
}
|
||||
|
||||
$record->save([
|
||||
'room_id' => $roomId,
|
||||
'update_time' => time(),
|
||||
]);
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
self::setError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static function recordingStatusText(int $status): string
|
||||
{
|
||||
$map = [
|
||||
0 => '无录制',
|
||||
1 => '录制中',
|
||||
2 => '已生成',
|
||||
3 => '录制失败',
|
||||
];
|
||||
|
||||
return $map[$status] ?? '未知';
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取TRTC配置
|
||||
@@ -1020,8 +1364,9 @@ class DiagnosisLogic extends BaseLogic
|
||||
throw new \Exception('小程序配置未设置');
|
||||
}
|
||||
|
||||
$scene = "id={$sceneId}&share_user={$shareUserId}&doctor_id={$doctorId}";
|
||||
|
||||
// 小程序 onLoad 解析 scene,须与前端 parsePageParams 约定一致(微信 scene 总长勿超过 32 字符)
|
||||
$scene = "id={$sceneId}&sa={$shareUserId}&did={$doctorId}";
|
||||
|
||||
// 调用微信接口生成小程序码
|
||||
$qrcodeUrl = self::generateWxQrcode($config, $page, $scene);
|
||||
|
||||
@@ -1051,13 +1396,20 @@ class DiagnosisLogic extends BaseLogic
|
||||
throw new \Exception('订单号不能为空');
|
||||
}
|
||||
|
||||
// 查询订单ID(使用ID代替订单号,更短)
|
||||
$order = \app\common\model\Order::where('order_no', $orderNo)->find();
|
||||
if (!$order) {
|
||||
throw new \Exception('订单不存在');
|
||||
}
|
||||
|
||||
$config = self::getMiniProgramConfig();
|
||||
if (!$config) {
|
||||
throw new \Exception('小程序配置未设置');
|
||||
}
|
||||
|
||||
$page = 'pages/order/order';
|
||||
$scene = "order_no={$orderNo}";
|
||||
// 微信小程序 scene 参数最大长度为32字符,使用订单ID代替订单号
|
||||
$scene = "id={$order->id}";
|
||||
|
||||
$qrcodeUrl = self::generateWxQrcode($config, $page, $scene);
|
||||
|
||||
@@ -1128,6 +1480,13 @@ class DiagnosisLogic extends BaseLogic
|
||||
// 调用微信接口生成小程序码
|
||||
$url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$accessToken}";
|
||||
|
||||
// 记录 scene 长度
|
||||
\think\facade\Log::info('Scene参数信息', [
|
||||
'scene' => $scene,
|
||||
'scene_length' => strlen($scene),
|
||||
'scene_urlencode_length' => strlen(urlencode($scene))
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'scene' => $scene,
|
||||
'page' => $page,
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\logic\tcm;
|
||||
|
||||
use app\common\logic\BaseLogic;
|
||||
use app\common\model\tcm\PrescriptionLibrary;
|
||||
|
||||
/**
|
||||
* 处方库逻辑层
|
||||
*/
|
||||
class PrescriptionLibraryLogic extends BaseLogic
|
||||
{
|
||||
/**
|
||||
* @notes 添加处方库
|
||||
*/
|
||||
public static function add(array $params): ?int
|
||||
{
|
||||
try {
|
||||
// 处理药材数据
|
||||
if (isset($params['herbs']) && is_array($params['herbs'])) {
|
||||
$params['herbs'] = json_encode($params['herbs'], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
$model = PrescriptionLibrary::create($params);
|
||||
return $model->id;
|
||||
} catch (\Exception $e) {
|
||||
self::setError($e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 编辑处方库
|
||||
*/
|
||||
public static function edit(array $params, int $adminId): bool
|
||||
{
|
||||
try {
|
||||
$model = PrescriptionLibrary::findOrEmpty($params['id']);
|
||||
if ($model->isEmpty()) {
|
||||
self::setError('处方不存在');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 权限检查:只有创建者或公开的处方才能编辑
|
||||
if ($model->creator_id != $adminId && $model->is_public != 1) {
|
||||
self::setError('无权限编辑此处方');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 处理药材数据
|
||||
if (isset($params['herbs']) && is_array($params['herbs'])) {
|
||||
$params['herbs'] = json_encode($params['herbs'], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
$model->save($params);
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
self::setError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 删除处方库
|
||||
*/
|
||||
public static function delete(int $id, int $adminId): bool
|
||||
{
|
||||
try {
|
||||
$model = PrescriptionLibrary::findOrEmpty($id);
|
||||
if ($model->isEmpty()) {
|
||||
self::setError('处方不存在');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 权限检查:只有创建者才能删除
|
||||
if ($model->creator_id != $adminId) {
|
||||
self::setError('无权限删除此处方');
|
||||
return false;
|
||||
}
|
||||
|
||||
$model->delete();
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
self::setError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 处方库详情
|
||||
*/
|
||||
public static function detail(int $id, int $adminId): ?array
|
||||
{
|
||||
try {
|
||||
$model = PrescriptionLibrary::findOrEmpty($id);
|
||||
if ($model->isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 权限检查:只有创建者或公开的处方才能查看
|
||||
if ($model->creator_id != $adminId && $model->is_public != 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = $model->toArray();
|
||||
|
||||
// 解析药材JSON
|
||||
if (!empty($data['herbs'])) {
|
||||
$data['herbs'] = json_decode($data['herbs'], true);
|
||||
} else {
|
||||
$data['herbs'] = [];
|
||||
}
|
||||
|
||||
return $data;
|
||||
} catch (\Exception $e) {
|
||||
self::setError($e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,10 +31,13 @@ class PrescriptionLogic
|
||||
*/
|
||||
public static function add(array $params, int $adminId): ?int
|
||||
{
|
||||
$diagnosis = Diagnosis::find($params['diagnosis_id']);
|
||||
if (!$diagnosis) {
|
||||
self::setError('诊单不存在');
|
||||
return null;
|
||||
// 如果没有诊单ID,允许直接创建处方模板
|
||||
if (!empty($params['diagnosis_id'])) {
|
||||
$diagnosis = Diagnosis::find($params['diagnosis_id']);
|
||||
if (!$diagnosis) {
|
||||
self::setError('诊单不存在');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$herbs = $params['herbs'] ?? [];
|
||||
@@ -57,27 +60,37 @@ class PrescriptionLogic
|
||||
|
||||
$data = [
|
||||
'sn' => $sn,
|
||||
'diagnosis_id' => (int)$params['diagnosis_id'],
|
||||
'prescription_name' => $params['prescription_name'] ?? '',
|
||||
'prescription_type' => $params['prescription_type'] ?? '浓缩水丸',
|
||||
'diagnosis_id' => (int)($params['diagnosis_id'] ?? 0),
|
||||
'appointment_id' => (int)($params['appointment_id'] ?? 0),
|
||||
'patient_id' => (int)$diagnosis->patient_id,
|
||||
'patient_name' => $params['patient_name'] ?? $diagnosis->patient_name,
|
||||
'gender' => (int)($params['gender'] ?? $diagnosis->gender),
|
||||
'age' => (int)($params['age'] ?? $diagnosis->age ?? 0),
|
||||
'phone' => $params['phone'] ?? $diagnosis->phone ?? '',
|
||||
'patient_id' => (int)($params['patient_id'] ?? 0),
|
||||
'patient_name' => $params['patient_name'] ?? '',
|
||||
'gender' => (int)($params['gender'] ?? 1),
|
||||
'age' => (int)($params['age'] ?? 0),
|
||||
'phone' => $params['phone'] ?? '',
|
||||
'visit_no' => $params['visit_no'] ?? $sn,
|
||||
'prescription_date' => $params['prescription_date'] ?? date('Y-m-d'),
|
||||
'pulse' => $params['pulse'] ?? $diagnosis->pulse ?? '',
|
||||
'tongue' => $params['tongue'] ?? $diagnosis->tongue_coating ?? '',
|
||||
'pulse' => $params['pulse'] ?? '',
|
||||
'pulse_condition' => $params['pulse_condition'] ?? '',
|
||||
'tongue' => $params['tongue'] ?? '',
|
||||
'tongue_image' => $params['tongue_image'] ?? '',
|
||||
'clinical_diagnosis' => $params['clinical_diagnosis'] ?? '',
|
||||
'case_record' => $params['case_record'] ?? null,
|
||||
'herbs' => $herbs,
|
||||
'dose_count' => (int)($params['dose_count'] ?? 1),
|
||||
'dose_unit' => $params['dose_unit'] ?? '剂',
|
||||
'usage_days' => (int)($params['usage_days'] ?? 7),
|
||||
'usage_instruction' => $params['usage_instruction'] ?? '水煎服一日二次',
|
||||
'usage_time' => $params['usage_time'] ?? '饭前',
|
||||
'usage_way' => $params['usage_way'] ?? '温水送服',
|
||||
'dietary_taboo' => is_array($params['dietary_taboo'] ?? null) ? implode(',', $params['dietary_taboo']) : ($params['dietary_taboo'] ?? ''),
|
||||
'usage_notes' => $params['usage_notes'] ?? '',
|
||||
'amount' => (float)($params['amount'] ?? 0),
|
||||
'doctor_name' => $params['doctor_name'] ?? '',
|
||||
'doctor_signature' => $params['doctor_signature'] ?? '',
|
||||
'template_id' => (int)($params['template_id'] ?? 0),
|
||||
'is_shared' => (int)($params['is_shared'] ?? 0),
|
||||
'creator_id' => $adminId,
|
||||
];
|
||||
|
||||
@@ -86,6 +99,91 @@ class PrescriptionLogic
|
||||
return (int)$prescription->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑处方
|
||||
*/
|
||||
public static function edit(array $params, int $adminId): bool
|
||||
{
|
||||
try {
|
||||
$prescription = Prescription::find($params['id']);
|
||||
if (!$prescription) {
|
||||
self::setError('处方不存在');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查权限:只有创建者或共享的处方才能编辑
|
||||
if ($prescription->creator_id != $adminId && $prescription->is_shared != 1) {
|
||||
self::setError('无权限编辑此处方');
|
||||
return false;
|
||||
}
|
||||
|
||||
$herbs = $params['herbs'] ?? [];
|
||||
if (empty($herbs) || !is_array($herbs)) {
|
||||
self::setError('请添加中药');
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($herbs as $h) {
|
||||
if (empty($h['name'])) {
|
||||
self::setError('中药名称不能为空');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
'prescription_name' => $params['prescription_name'] ?? $prescription->prescription_name,
|
||||
'prescription_type' => $params['prescription_type'] ?? $prescription->prescription_type,
|
||||
'patient_name' => $params['patient_name'] ?? $prescription->patient_name,
|
||||
'gender' => (int)($params['gender'] ?? $prescription->gender),
|
||||
'age' => (int)($params['age'] ?? $prescription->age),
|
||||
'visit_no' => $params['visit_no'] ?? $prescription->visit_no,
|
||||
'prescription_date' => $params['prescription_date'] ?? $prescription->prescription_date,
|
||||
'tongue' => $params['tongue'] ?? $prescription->tongue,
|
||||
'tongue_image' => $params['tongue_image'] ?? $prescription->tongue_image,
|
||||
'pulse' => $params['pulse'] ?? $prescription->pulse,
|
||||
'pulse_condition' => $params['pulse_condition'] ?? $prescription->pulse_condition,
|
||||
'clinical_diagnosis' => $params['clinical_diagnosis'] ?? $prescription->clinical_diagnosis,
|
||||
'herbs' => $herbs,
|
||||
'dose_count' => (int)($params['dose_count'] ?? $prescription->dose_count),
|
||||
'dose_unit' => $params['dose_unit'] ?? $prescription->dose_unit,
|
||||
'usage_days' => (int)($params['usage_days'] ?? $prescription->usage_days),
|
||||
'usage_instruction' => $params['usage_instruction'] ?? $prescription->usage_instruction,
|
||||
'usage_time' => $params['usage_time'] ?? $prescription->usage_time,
|
||||
'usage_way' => $params['usage_way'] ?? $prescription->usage_way,
|
||||
'dietary_taboo' => is_array($params['dietary_taboo'] ?? null) ? implode(',', $params['dietary_taboo']) : ($params['dietary_taboo'] ?? $prescription->dietary_taboo),
|
||||
'usage_notes' => $params['usage_notes'] ?? $prescription->usage_notes,
|
||||
'doctor_name' => $params['doctor_name'] ?? $prescription->doctor_name,
|
||||
'is_shared' => (int)($params['is_shared'] ?? $prescription->is_shared),
|
||||
];
|
||||
|
||||
$prescription->save($data);
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
self::setError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除处方
|
||||
*/
|
||||
public static function delete(int $id): bool
|
||||
{
|
||||
try {
|
||||
$prescription = Prescription::find($id);
|
||||
if (!$prescription) {
|
||||
self::setError('处方不存在');
|
||||
return false;
|
||||
}
|
||||
|
||||
$prescription->delete();
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
self::setError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处方详情
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user