first commit
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeadmin快速开发前后端分离管理后台(PHP版)
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\adminapi\controller\tcm;
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
use app\adminapi\logic\tcm\BloodRecordLogic;
|
||||
|
||||
/**
|
||||
* 血糖血压记录控制器
|
||||
* Class BloodRecordController
|
||||
* @package app\adminapi\controller\tcm
|
||||
*/
|
||||
class BloodRecordController extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* @notes 添加记录
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$result = BloodRecordLogic::add($params);
|
||||
if ($result) {
|
||||
return $this->success('添加成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(BloodRecordLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 编辑记录
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$result = BloodRecordLogic::edit($params);
|
||||
if ($result) {
|
||||
return $this->success('编辑成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(BloodRecordLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 删除记录
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$result = BloodRecordLogic::delete($params);
|
||||
if ($result) {
|
||||
return $this->success('删除成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(BloodRecordLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 记录详情
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
$result = BloodRecordLogic::detail($params);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取患者的记录列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getRecordsByPatient()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
$result = BloodRecordLogic::getRecordsByPatient($params);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取血糖趋势图数据
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getBloodSugarTrend()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
$result = BloodRecordLogic::getBloodSugarTrend($params);
|
||||
return $this->data($result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,972 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeadmin快速开发前后端分离管理后台(PHP版)
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
|
||||
// | github下载:https://github.com/likeshop-github/likeadmin
|
||||
// | 访问官网:https://www.likeadmin.cn
|
||||
// | likeadmin团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeadminTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\adminapi\controller\tcm;
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
use app\adminapi\lists\tcm\DiagnosisLists;
|
||||
use app\adminapi\logic\order\OrderActionLogLogic;
|
||||
use app\adminapi\logic\tcm\DiagnosisAiLogic;
|
||||
use app\adminapi\logic\tcm\DiagnosisLogic;
|
||||
use app\adminapi\logic\tcm\PatientAiReportLogic;
|
||||
use app\adminapi\logic\tcm\TrackingNoteLogic;
|
||||
use app\adminapi\validate\tcm\DiagnosisValidate;
|
||||
use app\common\model\Order;
|
||||
use app\common\model\WechatChatRecord;
|
||||
|
||||
/**
|
||||
* 中医辨房病因诊单控制器
|
||||
* Class DiagnosisController
|
||||
* @package app\adminapi\controller\tcm
|
||||
*/
|
||||
class DiagnosisController extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* @notes 测试接口
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function test()
|
||||
{
|
||||
return $this->success('中医诊单控制器可以访问', [
|
||||
'controller' => 'TcmDiagnosisController',
|
||||
'namespace' => __NAMESPACE__,
|
||||
'class' => __CLASS__,
|
||||
'method' => __METHOD__
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 诊单列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
return $this->dataLists(new DiagnosisLists());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 医助理诊单统计(按部门、按人)
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function assistantDiagnosisStats()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
$result = DiagnosisLogic::assistantDiagnosisStats($params, (int) $this->adminId, $this->adminInfo);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 添加诊单
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('add');
|
||||
// 诊单创建人(需表 zyt_tcm_diagnosis 已增加 admin_id 列,见 sql 脚本)
|
||||
$params['admin_id'] = (int) $this->adminId;
|
||||
$result = DiagnosisLogic::add($params);
|
||||
if ($result) {
|
||||
return $this->success('添加成功', ['id' => $result], 1, 1);
|
||||
}
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 编辑诊单
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('edit');
|
||||
$result = DiagnosisLogic::edit($params, $this->adminInfo);
|
||||
if ($result) {
|
||||
return $this->success('编辑成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 设置复诊接诊率统计起始偏移(业务订单 tab)
|
||||
*/
|
||||
public function setRevisitSlotStartOffset()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('setRevisitSlotStartOffset');
|
||||
$ok = DiagnosisLogic::setRevisitSlotStartOffset(
|
||||
(int) $params['id'],
|
||||
(int) $params['revisit_slot_start_offset'],
|
||||
$this->adminInfo
|
||||
);
|
||||
if (!$ok) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('保存成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 删除诊单
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('id');
|
||||
$result = DiagnosisLogic::delete($params);
|
||||
if ($result) {
|
||||
return $this->success('删除成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 诊单详情
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
|
||||
$params = (new DiagnosisValidate())->goCheck('id');
|
||||
$result = DiagnosisLogic::detail($params, $this->adminInfo);
|
||||
DiagnosisLogic::markAssignRead((int) ($params['id'] ?? 0), $this->adminId);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 二诊只读病例详情(患者信息 + 病例 + 跟踪记录)
|
||||
*
|
||||
* 路由:GET /tcm.diagnosis/readonlyDetail?id=:diagnosisId
|
||||
* 权限:tcm.diagnosis/readonlyDetail
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function readonlyDetail()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->goCheck('readonlyDetail');
|
||||
$result = DiagnosisLogic::readonlyDetail($params, $this->adminId, $this->adminInfo);
|
||||
if (empty($result)) {
|
||||
return $this->fail(DiagnosisLogic::getError() ?: '诊单不存在或无权访问');
|
||||
}
|
||||
DiagnosisLogic::markAssignRead((int) ($params['id'] ?? 0), $this->adminId);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 跟踪信息(血糖血压 / 饮食 / 运动)—— 按日期区间 lazy load
|
||||
*
|
||||
* 路由:GET /tcm.diagnosis/trackingWindow?id=:diagnosisId&start_date=&end_date=
|
||||
* 权限:tcm.diagnosis/readonlyDetail(与只读病例页同档;接诊台亦复用)
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function trackingWindow()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->goCheck('trackingWindow');
|
||||
$result = DiagnosisLogic::fetchTrackingWindow(
|
||||
(int) $params['id'],
|
||||
(string) ($params['start_date'] ?? ''),
|
||||
(string) ($params['end_date'] ?? '')
|
||||
);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 新增跟踪备注(按天合并追加,仅文字)
|
||||
*
|
||||
* 路由:POST /tcm.diagnosis/addTrackingNote
|
||||
* 权限:tcm.diagnosis/addTrackingNote
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function addTrackingNote()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('addTrackingNote');
|
||||
$ok = TrackingNoteLogic::addOrAppend([
|
||||
'diagnosis_id' => (int) $params['diagnosis_id'],
|
||||
'admin_id' => (int) $this->adminId,
|
||||
'content' => (string) $params['tracking_content'],
|
||||
]);
|
||||
if ($ok === false) {
|
||||
return $this->fail(TrackingNoteLogic::getError() ?: '保存失败');
|
||||
}
|
||||
return $this->success('保存成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 拉取跟踪备注列表(note_date DESC)
|
||||
*
|
||||
* 路由:GET /tcm.diagnosis/trackingNotes?diagnosis_id=:diagnosisId
|
||||
* 权限:tcm.diagnosis/trackingNotes
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function trackingNotes()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->goCheck('trackingNotes');
|
||||
return $this->data(TrackingNoteLogic::getByDiagnosis((int) $params['diagnosis_id']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 诊单挂号 / 取消挂号 操作日志(谁在何时操作)
|
||||
*/
|
||||
public function guahaoLogList()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->get()->goCheck('guahaoLogList');
|
||||
|
||||
return $this->data(DiagnosisLogic::guahaoLogList((int) $params['id']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 诊单详情(患者端)
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function diagnosisDetail()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
|
||||
if (empty($params['id'])) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
|
||||
if (empty($params['user_id'])) {
|
||||
return $this->fail('用户ID不能为空');
|
||||
}
|
||||
|
||||
$result = DiagnosisLogic::diagnosisDetail($params);
|
||||
if ($result) {
|
||||
return $this->data($result);
|
||||
}
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 检查手机号是否重复
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function checkPhone()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$result = DiagnosisLogic::checkPhone($params);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 检查身份证号是否重复
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function checkIdCard()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$result = DiagnosisLogic::checkIdCard($params);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 补全身份证号(自动计算年龄并更新)
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function fillIdCard()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('fillIdCard');
|
||||
$result = DiagnosisLogic::fillIdCard($params);
|
||||
if ($result) {
|
||||
return $this->success('补全成功,年龄已自动更新', [], 1, 1);
|
||||
}
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 指派医助
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function assign()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
|
||||
// 验证参数
|
||||
if (empty($params['id'])) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
|
||||
if (!array_key_exists('assistant_id', $params)) {
|
||||
return $this->fail('请选择医助或取消指派');
|
||||
}
|
||||
|
||||
$result = DiagnosisLogic::assign($params);
|
||||
if ($result) {
|
||||
$msg = (int) ($params['assistant_id'] ?? -1) === 0 ? '已取消指派' : '指派成功';
|
||||
|
||||
return $this->success($msg, [], 1, 1);
|
||||
}
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 指派医助操作记录
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function assignLogList()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->goCheck('id');
|
||||
$result = DiagnosisLogic::assignLogList((int) $params['id']);
|
||||
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取通话签名
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getCallSignature()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
|
||||
if (empty($params['diagnosis_id'])) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
|
||||
if (empty($params['patient_id'])) {
|
||||
return $this->fail('患者ID不能为空');
|
||||
}
|
||||
|
||||
// 传递当前管理员ID
|
||||
$params['admin_id'] = $this->adminId;
|
||||
|
||||
$result = DiagnosisLogic::getCallSignature($params);
|
||||
if ($result) {
|
||||
return $this->data($result);
|
||||
}
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 发起通话
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function startCall()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
|
||||
if (empty($params['diagnosis_id'])) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
|
||||
// 传递当前管理员ID
|
||||
$params['admin_id'] = $this->adminId;
|
||||
|
||||
$result = DiagnosisLogic::startCall($params, $this->adminInfo);
|
||||
if ($result !== false) {
|
||||
return $this->data($result);
|
||||
}
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
/** @notes 为当前医生的指定通话记录启动实时录音转写 */
|
||||
public function startCallTranscription()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$params['admin_id'] = (int)$this->adminId;
|
||||
$result = DiagnosisLogic::startCallTranscription($params);
|
||||
if ($result === false) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/** @notes 幂等写入当前通话的已完成转写分段 */
|
||||
public function upsertCallTranscriptSegments()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$params['admin_id'] = (int)$this->adminId;
|
||||
$result = DiagnosisLogic::upsertCallTranscriptSegments($params);
|
||||
if ($result === false) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/** @notes 完成当前通话转写并固化对话文字 */
|
||||
public function finishCallTranscription()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$params['admin_id'] = (int)$this->adminId;
|
||||
$result = DiagnosisLogic::finishCallTranscription($params);
|
||||
if ($result === false) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 结束通话
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function endCall()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
|
||||
if (empty($params['diagnosis_id'])) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
|
||||
// 传递当前管理员ID
|
||||
$params['admin_id'] = $this->adminId;
|
||||
|
||||
$result = DiagnosisLogic::endCall($params);
|
||||
if ($result) {
|
||||
return $this->success('', [], 1, 1);
|
||||
}
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取通话记录
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getCallRecords()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
|
||||
if (empty($params['diagnosis_id'])) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
|
||||
$result = DiagnosisLogic::getCallRecords($params);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取诊单关联的腾讯云 IM 单聊记录(admin_getroammsg)
|
||||
*/
|
||||
public function getImChatMessages()
|
||||
{
|
||||
// 增加执行时间限制到 120 秒
|
||||
set_time_limit(120);
|
||||
|
||||
$diagnosisId = (int)$this->request->get('diagnosis_id', 0);
|
||||
if ($diagnosisId <= 0) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
$onlyArchived = (int)$this->request->get('only_archived', 0) === 1;
|
||||
$result = DiagnosisLogic::getImChatMessagesForDiagnosis($diagnosisId, $onlyArchived);
|
||||
if ($result === false) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 触发后台异步同步当前诊单的腾讯云 IM 聊天记录到本地归档表
|
||||
* 请求即返回,真正的同步逻辑在 fastcgi_finish_request 之后执行
|
||||
*/
|
||||
public function triggerImChatSync()
|
||||
{
|
||||
$diagnosisId = (int)$this->request->post('diagnosis_id', 0);
|
||||
if ($diagnosisId <= 0) {
|
||||
$diagnosisId = (int)$this->request->get('diagnosis_id', 0);
|
||||
}
|
||||
if ($diagnosisId <= 0) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
|
||||
register_shutdown_function(function () use ($diagnosisId) {
|
||||
try {
|
||||
@set_time_limit(300);
|
||||
ignore_user_abort(true);
|
||||
DiagnosisLogic::syncImChatArchiveForDiagnosis($diagnosisId);
|
||||
} catch (\Throwable $e) {
|
||||
\think\facade\Log::warning('triggerImChatSync failed', [
|
||||
'diagnosis_id' => $diagnosisId,
|
||||
'err' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
return $this->success('已发起后台同步,几秒后请重新加载查看', ['queued' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 绑定 TRTC 房间号到当前诊单通话记录(便于云端录制回调关联)
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function bindCallRoom()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
if (empty($params['diagnosis_id'])) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
if (empty($params['room_id'])) {
|
||||
return $this->fail('房间号不能为空');
|
||||
}
|
||||
|
||||
$params['admin_id'] = (int)$this->adminId;
|
||||
$result = DiagnosisLogic::bindCallRoom($params);
|
||||
if ($result === false) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('', is_array($result) ? $result : [], 1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 接通后发起腾讯云云端混流录制(需配置 CAM 与云点播)
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function startCloudRecording()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
if (empty($params['diagnosis_id'])) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
$params['admin_id'] = (int)$this->adminId;
|
||||
$result = DiagnosisLogic::startCloudRecording($params);
|
||||
if ($result === false) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 浏览器本地上传通话录制后,关联到通话记录(合并 recording_urls)
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function attachLocalCallRecording()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
if (empty($params['diagnosis_id'])) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
if (empty($params['file_url'])) {
|
||||
return $this->fail('文件地址不能为空');
|
||||
}
|
||||
$params['admin_id'] = (int)$this->adminId;
|
||||
$result = DiagnosisLogic::attachLocalCallRecording($params);
|
||||
if ($result) {
|
||||
return $this->success('已关联录制', [], 1, 1);
|
||||
}
|
||||
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 手动上传视频前,先创建一条模拟通话记录
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function createManualCallRecord()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('trackingNotes');
|
||||
$result = DiagnosisLogic::createManualCallRecord([
|
||||
'diagnosis_id' => (int)$params['diagnosis_id'],
|
||||
'admin_id' => (int)$this->adminId,
|
||||
]);
|
||||
if (!$result) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('创建成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 医助旁观诊单当前视频通话(TRTC 进房参数,仅拉流)
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function watchCall()
|
||||
{
|
||||
$diagnosisId = (int)$this->request->get('diagnosis_id', 0);
|
||||
if ($diagnosisId <= 0) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
|
||||
$result = DiagnosisLogic::getAssistantWatchRoomParams([
|
||||
'diagnosis_id' => $diagnosisId,
|
||||
'admin_id' => (int)$this->adminId,
|
||||
]);
|
||||
if ($result === false) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取患者通话签名(用于测试)
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getDoctorSignature()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
|
||||
if (empty($params['patient_id'])) {
|
||||
return $this->fail('医助理ID不能为空');
|
||||
}
|
||||
|
||||
$result = DiagnosisLogic::getDoctorSignature((int)$params['patient_id']);
|
||||
if ($result) {
|
||||
return $this->data($result);
|
||||
}
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
/**
|
||||
* @notes 获取患者通话签名(用于测试)
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getPatientSignature()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
|
||||
if (empty($params['patient_id'])) {
|
||||
return $this->fail('患者ID不能为空');
|
||||
}
|
||||
|
||||
$result = DiagnosisLogic::getPatientSignature((int)$params['patient_id']);
|
||||
if ($result) {
|
||||
return $this->data($result);
|
||||
}
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取医助列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getAssistants()
|
||||
{
|
||||
$result = DiagnosisLogic::getAssistants((int) $this->adminId, $this->adminInfo);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取医生列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getDoctors()
|
||||
{
|
||||
$result = DiagnosisLogic::getDoctors();
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 生成小程序码
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function generateMiniProgramQrcode()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('generateQrcode');
|
||||
$result = DiagnosisLogic::generateMiniProgramQrcode($params);
|
||||
if ($result === false) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 生成订单小程序码
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function generateOrderQrcode()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$params['share_user_id'] = $this->adminId;
|
||||
$result = DiagnosisLogic::generateOrderQrcode($params);
|
||||
if ($result === false) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
$orderNo = (string)($params['order_no'] ?? '');
|
||||
if ($orderNo !== '') {
|
||||
$po = Order::where('order_no', $orderNo)->find();
|
||||
if ($po) {
|
||||
OrderActionLogLogic::record(
|
||||
(int)$po->id,
|
||||
(int)$this->adminId,
|
||||
$this->adminInfo,
|
||||
'wx_qrcode',
|
||||
'生成订单小程序码'
|
||||
);
|
||||
}
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取企业微信聊天记录
|
||||
*/
|
||||
public function getWechatChatRecords()
|
||||
{
|
||||
$diagnosisId = $this->request->get('diagnosis_id', 0);
|
||||
$patientId = $this->request->get('patient_id', 0);
|
||||
$pageNo = $this->request->get('page_no', 1);
|
||||
$pageSize = $this->request->get('page_size', 20);
|
||||
|
||||
if (empty($diagnosisId) && empty($patientId)) {
|
||||
return $this->fail('诊单ID或患者ID不能都为空');
|
||||
}
|
||||
|
||||
$query = WechatChatRecord::order('chat_time', 'desc');
|
||||
if ($diagnosisId) {
|
||||
$query->where('diagnosis_id', $diagnosisId);
|
||||
}
|
||||
if ($patientId) {
|
||||
$query->where('patient_id', $patientId);
|
||||
}
|
||||
|
||||
$count = (clone $query)->count();
|
||||
$lists = $query->page($pageNo, $pageSize)->select()->toArray();
|
||||
|
||||
return $this->data([
|
||||
'lists' => $lists,
|
||||
'count' => $count,
|
||||
'page_no' => $pageNo,
|
||||
'page_size' => $pageSize
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 添加企业微信聊天记录(手动录入/同步写入)
|
||||
*/
|
||||
public function addWechatChatRecord()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
|
||||
if (empty($params['diagnosis_id']) && empty($params['patient_id'])) {
|
||||
return $this->fail('诊单ID或患者ID不能都为空');
|
||||
}
|
||||
if (empty($params['content'])) {
|
||||
return $this->fail('内容不能为空');
|
||||
}
|
||||
|
||||
$adminInfo = $this->adminInfo;
|
||||
|
||||
$data = [
|
||||
'diagnosis_id' => $params['diagnosis_id'] ?? 0,
|
||||
'patient_id' => $params['patient_id'] ?? 0,
|
||||
'staff_userid' => $adminInfo['work_wechat_userid'] ?? ($params['staff_userid'] ?? ''),
|
||||
'staff_name' => $params['staff_name'] ?? ($adminInfo['name'] ?? ''),
|
||||
'external_userid' => $params['external_userid'] ?? '',
|
||||
'external_name' => $params['external_name'] ?? '',
|
||||
'msg_type' => $params['msg_type'] ?? 'note',
|
||||
'content' => $params['content'],
|
||||
'media_url' => $params['media_url'] ?? '',
|
||||
'chat_time' => $params['chat_time'] ?? time(),
|
||||
'direction' => $params['direction'] ?? 0,
|
||||
'create_time' => time(),
|
||||
];
|
||||
|
||||
$record = WechatChatRecord::create($data);
|
||||
|
||||
return $this->success('添加成功', ['id' => $record->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 删除企业微信聊天记录
|
||||
*/
|
||||
public function deleteWechatChatRecord()
|
||||
{
|
||||
$id = $this->request->post('id', 0);
|
||||
if (empty($id)) {
|
||||
return $this->fail('记录ID不能为空');
|
||||
}
|
||||
|
||||
WechatChatRecord::destroy($id);
|
||||
return $this->success('删除成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 同步企业微信外部联系人信息(查找该患者在企业微信中的跟进人)
|
||||
*/
|
||||
public function getWechatExternalContact()
|
||||
{
|
||||
$patientId = $this->request->get('patient_id', 0);
|
||||
if (empty($patientId)) {
|
||||
return $this->fail('患者ID不能为空');
|
||||
}
|
||||
|
||||
$result = DiagnosisLogic::getWechatExternalContact($patientId);
|
||||
if ($result === false) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取会话内容存档开启的成员列表
|
||||
*/
|
||||
public function getMsgAuditPermitUsers()
|
||||
{
|
||||
$result = DiagnosisLogic::getMsgAuditPermitUsers();
|
||||
if ($result === false) {
|
||||
return $this->fail(DiagnosisLogic::getError());
|
||||
}
|
||||
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 搜索患者(用于创建订单等场景)
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function searchPatient()
|
||||
{
|
||||
$keyword = $this->request->get('keyword', '');
|
||||
$page_no = $this->request->get('page_no', 1);
|
||||
$page_size = $this->request->get('page_size', 10);
|
||||
|
||||
if (empty($keyword)) {
|
||||
return $this->success('', ['lists' => [], 'count' => 0]);
|
||||
}
|
||||
|
||||
$offset = ($page_no - 1) * $page_size;
|
||||
|
||||
$lists = \app\common\model\tcm\Diagnosis::where('patient_name|phone|id_card', 'like', '%' . $keyword . '%')
|
||||
->field(['id', 'patient_name', 'phone', 'id_card', 'gender', 'age'])
|
||||
->limit($offset, $page_size)
|
||||
->order('id desc')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$count = \app\common\model\tcm\Diagnosis::where('patient_name|phone|id_card', 'like', '%' . $keyword . '%')
|
||||
->count();
|
||||
|
||||
return $this->success('', [
|
||||
'lists' => $lists,
|
||||
'count' => $count,
|
||||
'page_no' => $page_no,
|
||||
'page_size' => $page_size
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 读取已保存的双模型诊单 AI 报告,不触发上游调用
|
||||
*/
|
||||
public function aiReports()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->get()->goCheck('aiReports');
|
||||
$reports = DiagnosisAiLogic::getSavedReports(
|
||||
(int) $params['id'],
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($reports === null) {
|
||||
return $this->fail(DiagnosisAiLogic::getError());
|
||||
}
|
||||
return $this->data($reports);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 基于当前授权诊单向 AI 助手提问,不接收客户端上游配置
|
||||
*/
|
||||
public function aiAssistant()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('aiAssistant');
|
||||
$result = DiagnosisAiLogic::assistant(
|
||||
(int) $params['id'],
|
||||
(string) $params['task'],
|
||||
(string) ($params['prompt'] ?? ''),
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === null) {
|
||||
return $this->fail(DiagnosisAiLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 对当前授权诊单生成一次结构化 AI 智能分析,仅接受 qwen/openai 模型键
|
||||
*/
|
||||
public function aiAnalysis()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('aiAnalysis');
|
||||
$result = DiagnosisAiLogic::analysis(
|
||||
(int) $params['id'],
|
||||
$this->adminId,
|
||||
$this->adminInfo,
|
||||
(string) ($params['model'] ?? 'qwen')
|
||||
);
|
||||
if ($result === null) {
|
||||
return $this->fail(DiagnosisAiLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 查询患者级 AI 诊断报告全部历史及各模型最新版本,不触发模型调用
|
||||
*/
|
||||
public function patientAiReports()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->get()->goCheck('patientAiReports');
|
||||
$result = PatientAiReportLogic::reports(
|
||||
(int) $params['patient_id'],
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === null) {
|
||||
return $this->fail(PatientAiReportLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 聚合当前数据域内患者纵向资料,调用指定固定模型并新增一份不可变报告快照
|
||||
*/
|
||||
public function generatePatientAiReport()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('generatePatientAiReport');
|
||||
$result = PatientAiReportLogic::generate(
|
||||
(int) $params['patient_id'],
|
||||
(string) $params['model'],
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === null) {
|
||||
return $this->fail(PatientAiReportLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 整份重新生成两个固定模型的诊单 AI 报告并保存成功项
|
||||
*/
|
||||
public function generateAiReports()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('generateAiReports');
|
||||
$reports = DiagnosisAiLogic::generateAll(
|
||||
(int) $params['id'],
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($reports === null) {
|
||||
return $this->fail(DiagnosisAiLogic::getError());
|
||||
}
|
||||
return $this->data($reports);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 编辑一份已保存的诊单 AI 报告
|
||||
*/
|
||||
public function editAiReport()
|
||||
{
|
||||
$params = (new DiagnosisValidate())->post()->goCheck('editAiReport');
|
||||
$report = DiagnosisAiLogic::editReport(
|
||||
(int) $params['id'],
|
||||
(int) $params['report_id'],
|
||||
$params['content'] ?? null,
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($report === null) {
|
||||
return $this->fail(DiagnosisAiLogic::getError());
|
||||
}
|
||||
return $this->data($report);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeadmin快速开发前后端分离管理后台(PHP版)
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
|
||||
// | github下载:https://github.com/likeshop-github/likeadmin
|
||||
// | 访问官网:https://www.likeadmin.cn
|
||||
// | likeadmin团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeadminTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\controller\tcm;
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
use app\adminapi\lists\tcm\DiagnosisTodoLists;
|
||||
use app\adminapi\logic\tcm\DiagnosisTodoLogic;
|
||||
use app\adminapi\validate\tcm\DiagnosisTodoValidate;
|
||||
|
||||
/**
|
||||
* 诊单待办事项控制器
|
||||
*
|
||||
* 职责:仅 lists / add / cancel / detail;编辑能力故意不开放(要改 = 取消重建)
|
||||
*
|
||||
* @package app\adminapi\controller\tcm
|
||||
*/
|
||||
class DiagnosisTodoController extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* @notes 待办列表(按 diagnosis_id)
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
(new DiagnosisTodoValidate())->goCheck('list');
|
||||
|
||||
return $this->dataLists(new DiagnosisTodoLists());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 新增待办
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$params = (new DiagnosisTodoValidate())->post()->goCheck('add');
|
||||
$result = DiagnosisTodoLogic::add($params, $this->adminId, $this->adminInfo);
|
||||
if (!$result) {
|
||||
return $this->fail(DiagnosisTodoLogic::getError() ?: '创建失败');
|
||||
}
|
||||
|
||||
return $this->success('创建成功', [], 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 取消待办(仅 status=0 可取消,仅创建人/超管)
|
||||
*/
|
||||
public function cancel()
|
||||
{
|
||||
$params = (new DiagnosisTodoValidate())->post()->goCheck('cancel');
|
||||
$result = DiagnosisTodoLogic::cancel((int) $params['id'], $this->adminId);
|
||||
if (!$result) {
|
||||
return $this->fail(DiagnosisTodoLogic::getError() ?: '取消失败');
|
||||
}
|
||||
|
||||
return $this->success('已取消', [], 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 待办详情
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
$params = (new DiagnosisTodoValidate())->goCheck('detail');
|
||||
$result = DiagnosisTodoLogic::detail((int) $params['id'], $this->adminId);
|
||||
|
||||
return $this->data($result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\tcm;
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
use app\adminapi\logic\tcm\DietRecordLogic;
|
||||
|
||||
class DietRecordController extends BaseAdminController
|
||||
{
|
||||
public function add()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$result = DietRecordLogic::add($params);
|
||||
if ($result) {
|
||||
return $this->success('添加成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(DietRecordLogic::getError());
|
||||
}
|
||||
|
||||
public function edit()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$result = DietRecordLogic::edit($params);
|
||||
if ($result) {
|
||||
return $this->success('编辑成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(DietRecordLogic::getError());
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$result = DietRecordLogic::delete($params);
|
||||
if ($result) {
|
||||
return $this->success('删除成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(DietRecordLogic::getError());
|
||||
}
|
||||
|
||||
public function detail()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
$result = DietRecordLogic::detail($params);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
public function getRecordsByPatient()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
$result = DietRecordLogic::getRecordsByPatient($params);
|
||||
return $this->data($result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\tcm;
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
use app\adminapi\logic\tcm\ExerciseRecordLogic;
|
||||
|
||||
class ExerciseRecordController extends BaseAdminController
|
||||
{
|
||||
public function add()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$result = ExerciseRecordLogic::add($params);
|
||||
if ($result) {
|
||||
return $this->success('添加成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(ExerciseRecordLogic::getError());
|
||||
}
|
||||
|
||||
public function edit()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$result = ExerciseRecordLogic::edit($params);
|
||||
if ($result) {
|
||||
return $this->success('编辑成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(ExerciseRecordLogic::getError());
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
$result = ExerciseRecordLogic::delete($params);
|
||||
if ($result) {
|
||||
return $this->success('删除成功', [], 1, 1);
|
||||
}
|
||||
return $this->fail(ExerciseRecordLogic::getError());
|
||||
}
|
||||
|
||||
public function detail()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
$result = ExerciseRecordLogic::detail($params);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
public function getRecordsByPatient()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
$result = ExerciseRecordLogic::getRecordsByPatient($params);
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
public function getExerciseTrend()
|
||||
{
|
||||
$params = $this->request->get();
|
||||
$result = ExerciseRecordLogic::getExerciseTrend($params);
|
||||
return $this->data($result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\controller\tcm;
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
use app\adminapi\logic\tcm\PrescriptionLogic;
|
||||
use app\adminapi\validate\tcm\PrescriptionValidate;
|
||||
|
||||
/**
|
||||
* 中医处方单控制器
|
||||
*/
|
||||
class PrescriptionController extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* @notes 处方列表
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
return $this->dataLists(new \app\adminapi\lists\tcm\PrescriptionLists());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 添加处方
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$params = (new PrescriptionValidate())->post()->goCheck('add');
|
||||
$params['creator_id'] = $this->adminId;
|
||||
$id = PrescriptionLogic::add($params, $this->adminId);
|
||||
if ($id === null) {
|
||||
return $this->fail(PrescriptionLogic::getError());
|
||||
}
|
||||
return $this->success('保存成功', ['id' => $id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 编辑处方
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$params = (new PrescriptionValidate())->post()->goCheck('edit');
|
||||
$result = PrescriptionLogic::edit($params, $this->adminId);
|
||||
if (!$result) {
|
||||
return $this->fail(PrescriptionLogic::getError());
|
||||
}
|
||||
return $this->success('编辑成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 修正处方患者姓名手机性别
|
||||
*/
|
||||
public function patchPatient()
|
||||
{
|
||||
$params = (new PrescriptionValidate())->post()->goCheck('patchPatient');
|
||||
$ok = PrescriptionLogic::patchPatientContact(
|
||||
(int) $params['id'],
|
||||
(string) $params['patient_name'],
|
||||
(string) $params['phone'],
|
||||
(int) $params['gender'],
|
||||
(int) $this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if (!$ok) {
|
||||
return $this->fail(PrescriptionLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('已更新');
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 删除处方
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$params = (new PrescriptionValidate())->post()->goCheck('delete');
|
||||
$result = PrescriptionLogic::delete($params['id']);
|
||||
if (!$result) {
|
||||
return $this->fail(PrescriptionLogic::getError());
|
||||
}
|
||||
return $this->success('删除成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 处方详情
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
$params = (new PrescriptionValidate())->get()->goCheck('detail');
|
||||
$detail = PrescriptionLogic::detail((int) $params['id'], (int) $this->adminId, $this->adminInfo);
|
||||
|
||||
if (!$detail) {
|
||||
$msg = PrescriptionLogic::getError();
|
||||
|
||||
return $this->fail($msg !== '' ? $msg : '处方不存在');
|
||||
}
|
||||
|
||||
return $this->data($detail);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 审核处方(通过 / 驳回,驳回即作废)
|
||||
*/
|
||||
public function audit()
|
||||
{
|
||||
$params = (new PrescriptionValidate())->post()->goCheck('audit');
|
||||
$ok = PrescriptionLogic::audit(
|
||||
(int) $params['id'],
|
||||
(string) $params['action'],
|
||||
(string) ($params['remark'] ?? ''),
|
||||
(int) $this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if (!$ok) {
|
||||
return $this->fail(PrescriptionLogic::getError());
|
||||
}
|
||||
|
||||
$msg = $params['action'] === 'reject' ? '已驳回并作废处方' : '审核通过';
|
||||
$wecom = PrescriptionLogic::consumeLastAuditWecomNotify();
|
||||
$data = [];
|
||||
if (is_array($wecom)) {
|
||||
$data['wecom_notify_ok'] = !empty($wecom['ok']);
|
||||
if (empty($wecom['ok']) && !empty($wecom['message'])) {
|
||||
$data['wecom_notify_hint'] = (string) $wecom['message'];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success($msg, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 根据诊单获取处方列表
|
||||
*/
|
||||
public function listByDiagnosis()
|
||||
{
|
||||
$diagnosisId = (int)($this->request->get('diagnosis_id') ?? 0);
|
||||
if (!$diagnosisId) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
}
|
||||
$list = PrescriptionLogic::listByDiagnosis($diagnosisId);
|
||||
return $this->data($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 根据预约获取处方
|
||||
*/
|
||||
public function getByAppointment()
|
||||
{
|
||||
$appointmentId = (int)($this->request->get('appointment_id') ?? 0);
|
||||
if (!$appointmentId) {
|
||||
return $this->fail('预约ID不能为空');
|
||||
}
|
||||
$prescription = PrescriptionLogic::getByAppointment($appointmentId, (int)$this->adminId, $this->adminInfo);
|
||||
if ($prescription === null) {
|
||||
$msg = PrescriptionLogic::getError();
|
||||
if ($msg !== '') {
|
||||
return $this->fail($msg);
|
||||
}
|
||||
return $this->data([]);
|
||||
}
|
||||
return $this->data($prescription);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 作废处方
|
||||
*/
|
||||
public function void()
|
||||
{
|
||||
$id = (int)($this->request->post('id') ?? 0);
|
||||
if (!$id) {
|
||||
return $this->fail('处方ID不能为空');
|
||||
}
|
||||
$admin = $this->adminInfo;
|
||||
$ok = PrescriptionLogic::void($id, (int)$this->adminId, $admin['name'] ?? '');
|
||||
if (!$ok) {
|
||||
return $this->fail(PrescriptionLogic::getError());
|
||||
}
|
||||
return $this->success('作废成功');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\controller\tcm;
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
use app\adminapi\logic\tcm\PrescriptionLibraryAiLogic;
|
||||
use app\adminapi\logic\tcm\PrescriptionLibraryLogic;
|
||||
use app\adminapi\validate\tcm\PrescriptionLibraryValidate;
|
||||
|
||||
/**
|
||||
* 处方库控制器
|
||||
*/
|
||||
class PrescriptionLibraryController extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* @notes 处方库列表
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
return $this->dataLists(new \app\adminapi\lists\tcm\PrescriptionLibraryLists());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 添加处方库
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$params = (new PrescriptionLibraryValidate())->post()->goCheck('add');
|
||||
$params['creator_id'] = $this->adminId;
|
||||
$params['creator_name'] = $this->adminInfo['name'] ?? '';
|
||||
$id = PrescriptionLibraryLogic::add($params);
|
||||
if ($id === null) {
|
||||
return $this->fail(PrescriptionLibraryLogic::getError());
|
||||
}
|
||||
return $this->success('保存成功', ['id' => $id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 编辑处方库
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$params = (new PrescriptionLibraryValidate())->post()->goCheck('edit');
|
||||
$canAll = PrescriptionLibraryLogic::canManageAllPrescriptions($this->adminId, $this->adminInfo);
|
||||
$result = PrescriptionLibraryLogic::edit($params, $this->adminId, $canAll);
|
||||
if (!$result) {
|
||||
return $this->fail(PrescriptionLibraryLogic::getError());
|
||||
}
|
||||
return $this->success('编辑成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 删除处方库
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$params = (new PrescriptionLibraryValidate())->post()->goCheck('delete');
|
||||
$canAll = PrescriptionLibraryLogic::canManageAllPrescriptions($this->adminId, $this->adminInfo);
|
||||
$result = PrescriptionLibraryLogic::delete((int) $params['id'], $this->adminId, $canAll);
|
||||
if (!$result) {
|
||||
return $this->fail(PrescriptionLibraryLogic::getError());
|
||||
}
|
||||
return $this->success('删除成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 处方库详情
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
$params = (new PrescriptionLibraryValidate())->get()->goCheck('detail');
|
||||
$canAll = PrescriptionLibraryLogic::canManageAllPrescriptions($this->adminId, $this->adminInfo);
|
||||
$detail = PrescriptionLibraryLogic::detail((int) $params['id'], $this->adminId, $canAll);
|
||||
if (!$detail) {
|
||||
return $this->fail('处方不存在或无权限查看');
|
||||
}
|
||||
return $this->data($detail);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 读取已保存的双模型 AI 解释,不触发上游调用
|
||||
*/
|
||||
public function aiReports()
|
||||
{
|
||||
$params = (new PrescriptionLibraryValidate())->get()->goCheck('aiReports');
|
||||
$reports = PrescriptionLibraryAiLogic::getSavedReports(
|
||||
(int) $params['id'],
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($reports === null) {
|
||||
return $this->fail(PrescriptionLibraryAiLogic::getError());
|
||||
}
|
||||
return $this->data($reports);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 查询当前数据范围内完全没有 AI 报告的处方,不触发上游调用
|
||||
*/
|
||||
public function missingAiReports()
|
||||
{
|
||||
$params = (new PrescriptionLibraryValidate())->get()->goCheck('missingAiReports');
|
||||
$result = PrescriptionLibraryAiLogic::getMissingReports(
|
||||
(int) ($params['limit'] ?? 500),
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === null) {
|
||||
return $this->fail(PrescriptionLibraryAiLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 整份重新生成两个固定模型的 AI 解释并保存成功项
|
||||
*/
|
||||
public function generateAiReports()
|
||||
{
|
||||
$params = (new PrescriptionLibraryValidate())->post()->goCheck('generateAiReports');
|
||||
$reports = PrescriptionLibraryAiLogic::generateAll(
|
||||
(int) $params['id'],
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($reports === null) {
|
||||
return $this->fail(PrescriptionLibraryAiLogic::getError());
|
||||
}
|
||||
return $this->data($reports);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 编辑一份已保存的 AI 解释
|
||||
*/
|
||||
public function editAiReport()
|
||||
{
|
||||
$params = (new PrescriptionLibraryValidate())->post()->goCheck('editAiReport');
|
||||
$report = PrescriptionLibraryAiLogic::editReport(
|
||||
(int) $params['id'],
|
||||
(int) $params['report_id'],
|
||||
$params['content'] ?? null,
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($report === null) {
|
||||
return $this->fail(PrescriptionLibraryAiLogic::getError());
|
||||
}
|
||||
return $this->data($report);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,560 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\controller\tcm;
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
use app\adminapi\lists\tcm\PrescriptionOrderLists;
|
||||
use app\adminapi\logic\order\OrderLogic;
|
||||
use app\adminapi\logic\tcm\PrescriptionOrderLogic;
|
||||
use app\adminapi\validate\tcm\PrescriptionOrderValidate;
|
||||
|
||||
/**
|
||||
* 处方业务订单(非支付单)
|
||||
*/
|
||||
class PrescriptionOrderController extends BaseAdminController
|
||||
{
|
||||
public function lists()
|
||||
{
|
||||
return $this->dataLists(new PrescriptionOrderLists());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处方业务订单导出(与 lists 相同筛选条件,Excel;参数 export=1 预估 export=2 下载)
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
return $this->dataLists(new PrescriptionOrderLists());
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定诊单下可关联的支付单(待支付/已支付,创建/编辑业务订单时多选关联)
|
||||
*/
|
||||
public function paidPayOrders()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->get()->goCheck('paidPayOrders');
|
||||
$exceptPo = (int) $this->request->get('prescription_order_id', 0);
|
||||
|
||||
$lists = OrderLogic::listPaidOrdersForDiagnosis(
|
||||
(int) $params['diagnosis_id'],
|
||||
$this->adminId,
|
||||
$this->adminInfo,
|
||||
$exceptPo > 0 ? $exceptPo : null
|
||||
);
|
||||
|
||||
$min = PrescriptionOrderLogic::depositMinAmount();
|
||||
|
||||
// if ($min > 0) {
|
||||
// $lists = array_values(array_filter(
|
||||
// $lists,
|
||||
// static fn(array $r): bool => round((float) ($r['amount'] ?? 0), 2) >= $min
|
||||
// ));
|
||||
// }
|
||||
|
||||
return $this->success('', [
|
||||
'lists' => $lists,
|
||||
'deposit_min_amount' => $min,
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('create');
|
||||
$result = PrescriptionOrderLogic::create($params, $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('创建成功', $result);
|
||||
}
|
||||
|
||||
public function detail()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->get()->goCheck('detail');
|
||||
$detail = PrescriptionOrderLogic::detail((int) $params['id'], $this->adminId, $this->adminInfo);
|
||||
if ($detail === null) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->data($detail);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快递轨迹查询(对接快递100;未配置时仍可跳转顺丰/京东官网)
|
||||
*/
|
||||
public function logisticsTrace()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->get()->goCheck('logisticsTrace');
|
||||
$expressOverride = trim((string) $this->request->get('express_company', ''));
|
||||
$phoneTail = trim((string) ($params['phone_tail'] ?? ''));
|
||||
$data = PrescriptionOrderLogic::logisticsTrace(
|
||||
(int) $params['id'],
|
||||
$expressOverride,
|
||||
$this->adminId,
|
||||
$this->adminInfo,
|
||||
$phoneTail
|
||||
);
|
||||
if ($data === null) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接调用京东官方物流接口刷新轨迹并落库(绕过快递100缓存)
|
||||
*/
|
||||
public function logisticsJdUpdate()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('logisticsJdUpdate');
|
||||
$data = PrescriptionOrderLogic::logisticsJdUpdate(
|
||||
(int) $params['id'],
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($data === null) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success((string) ($data['message'] ?? '京东物流轨迹已更新'), $data);
|
||||
}
|
||||
|
||||
public function edit()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('edit');
|
||||
$result = PrescriptionOrderLogic::edit($params, $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('保存成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅修改承运商与快递单号,不受订单履约状态或远端药房快照锁限制。
|
||||
*/
|
||||
public function ddcode()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('ddcode');
|
||||
$result = PrescriptionOrderLogic::ddcode(
|
||||
(int) $params['id'],
|
||||
(string) ($params['express_company'] ?? 'auto'),
|
||||
(string) $params['tracking_number'],
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('快递单号已保存', $result);
|
||||
}
|
||||
|
||||
public function updateAmount()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('updateAmount');
|
||||
$result = PrescriptionOrderLogic::updateAmount($params, $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('修改成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置发货类型(甘草 / 洛阳)
|
||||
*/
|
||||
public function setShipMode()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('setShipMode');
|
||||
$result = PrescriptionOrderLogic::setShipMode(
|
||||
(int) $params['id'],
|
||||
(string) ($params['ship_mode'] ?? 'gancao'),
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('已保存', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 人工核对甘草不确定提交:确认远端成功或确认未创建。
|
||||
*/
|
||||
public function confirmGancaoSubmission()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('confirmGancaoSubmission');
|
||||
$result = PrescriptionOrderLogic::confirmGancaoSubmission(
|
||||
(int) $params['id'],
|
||||
(string) $params['resolution'],
|
||||
(string) ($params['remote_order_no'] ?? ''),
|
||||
(string) $params['note'],
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('甘草提交核对已记录', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改关联处方的患者姓名与手机号(订单详情场景)
|
||||
*/
|
||||
public function patchPrescriptionPatient()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('patchPrescriptionPatient');
|
||||
$ok = PrescriptionOrderLogic::patchPrescriptionPatient(
|
||||
(int) $params['id'],
|
||||
(string) $params['patient_name'],
|
||||
(string) $params['phone'],
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if (!$ok) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('保存成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改关联处方服用参数(主方/辅方次数与开立天数)及订单服用天数
|
||||
*/
|
||||
public function patchPrescriptionUsage()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('patchPrescriptionUsage');
|
||||
$ok = PrescriptionOrderLogic::patchPrescriptionUsage($params, $this->adminId, $this->adminInfo);
|
||||
if (!$ok) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('保存成功');
|
||||
}
|
||||
|
||||
public function auditPrescription()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('auditPrescription');
|
||||
$result = PrescriptionOrderLogic::auditPrescription(
|
||||
(int) $params['id'],
|
||||
(string) $params['action'],
|
||||
(string) ($params['remark'] ?? ''),
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('操作成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回处方审核
|
||||
*/
|
||||
public function revokeRxAudit()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('detail');
|
||||
$result = PrescriptionOrderLogic::revokeRxAudit(
|
||||
(int) $params['id'],
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('处方审核已撤回', $result);
|
||||
}
|
||||
|
||||
public function auditPayment()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('auditPayment');
|
||||
$result = PrescriptionOrderLogic::auditPaymentSlip(
|
||||
(int) $params['id'],
|
||||
(string) $params['action'],
|
||||
(string) ($params['remark'] ?? ''),
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('操作成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回支付单审核
|
||||
*/
|
||||
public function revokePayAudit()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('detail');
|
||||
$result = PrescriptionOrderLogic::revokePayAudit(
|
||||
(int) $params['id'],
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('支付单审核已撤回', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认发货:将履约状态推进到 5(已发货),同时更新快递信息
|
||||
*/
|
||||
public function ship()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('ship');
|
||||
$result = PrescriptionOrderLogic::ship(
|
||||
(int) $params['id'],
|
||||
(string) ($params['express_company'] ?? 'auto'),
|
||||
(string) ($params['tracking_number'] ?? ''),
|
||||
(string) ($params['ship_mode'] ?? 'gancao'),
|
||||
$this->adminId,
|
||||
$this->adminInfo
|
||||
);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('发货成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 医助/创建人撤回:仅「待双审通过」可撤(未通过或双审均驳回等仍为该状态)
|
||||
*/
|
||||
public function withdraw()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('withdraw');
|
||||
$result = PrescriptionOrderLogic::withdraw((int) $params['id'], $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('已撤回', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 批量将处方业务订单改派给其他医助(写入 creator_id 并逐单记操作日志)
|
||||
*/
|
||||
public function batchAssignAssistant()
|
||||
{
|
||||
if (!PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
|
||||
return $this->fail('无权限批量改派订单');
|
||||
}
|
||||
$params = $this->request->post();
|
||||
$rawIds = $params['order_ids'] ?? [];
|
||||
if (!\is_array($rawIds) || $rawIds === []) {
|
||||
return $this->fail('请选择订单');
|
||||
}
|
||||
$assistantId = (int) ($params['assistant_id'] ?? 0);
|
||||
$result = PrescriptionOrderLogic::batchAssignAssistant($rawIds, $assistantId, $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
$msg = '已改派 ' . (int) $result['success'] . ' 单';
|
||||
if (!empty($result['errors'])) {
|
||||
$msg .= ';' . implode(';', $result['errors']);
|
||||
}
|
||||
|
||||
return $this->success($msg, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取业务订单操作日志
|
||||
*/
|
||||
public function logs()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->get()->goCheck('logs');
|
||||
$result = PrescriptionOrderLogic::getLogs((int) $params['id'], $this->adminId, $this->adminInfo);
|
||||
|
||||
// 遇到没有权限或者订单不存在,逻辑里设置了 self::$error
|
||||
if ($result === [] && PrescriptionOrderLogic::getError() !== '') {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手工新增操作日志(可选同步调整处方/支付单审核状态)
|
||||
*/
|
||||
public function addLog()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('addLog');
|
||||
$result = PrescriptionOrderLogic::addLog($params, $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('日志已添加', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为「已发货」订单新增一条关联支付单,并重置支付单审核状态为待审核
|
||||
*/
|
||||
public function addPayOrder()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('addPayOrder');
|
||||
$result = PrescriptionOrderLogic::addPayOrder($params, $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('新增支付单成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为「已发货」订单关联已有支付单,并重置支付单审核状态为待审核
|
||||
*/
|
||||
public function linkPayOrder()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('linkPayOrder');
|
||||
$result = PrescriptionOrderLogic::linkPayOrder($params, $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('关联支付单成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 已发货/已签收:仅提交完单申请(不新增/关联支付单),并重置支付审核为待审核
|
||||
*/
|
||||
public function requestCompletion()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('requestCompletion');
|
||||
$result = PrescriptionOrderLogic::requestCompletion($params, $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('完单申请已提交', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将「已发货」且支付审核已通过的订单标记为「已完成」
|
||||
*/
|
||||
public function complete()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('complete');
|
||||
$result = PrescriptionOrderLogic::complete(
|
||||
(int) $params['id'],
|
||||
$this->adminId,
|
||||
$this->adminInfo,
|
||||
(int) $params['fulfillment_status']
|
||||
);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('操作成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务订单退款(须填写原因;关联收款单标记已退款)
|
||||
*/
|
||||
public function refund()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('refund');
|
||||
$rawRefundAmount = $params['refund_amount'] ?? null;
|
||||
$refundAmount = ($rawRefundAmount === null || $rawRefundAmount === '')
|
||||
? null
|
||||
: round((float) $rawRefundAmount, 2);
|
||||
|
||||
$result = PrescriptionOrderLogic::refund(
|
||||
(int) $params['id'],
|
||||
(string) ($params['reason'] ?? ''),
|
||||
$this->adminId,
|
||||
$this->adminInfo,
|
||||
$refundAmount
|
||||
);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
|
||||
return $this->success('退款成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 甘草药管家:处方下单(CTM_PREVIEW → CTM_SUBMIT_RECIPEL)
|
||||
*
|
||||
* @see https://apidoc.igancao.com/service-doc/scm-outer-recipel.html
|
||||
*/
|
||||
public function submitGancaoRecipel()
|
||||
{
|
||||
try {
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('submitGancaoRecipel');
|
||||
$result = PrescriptionOrderLogic::uploadToPharmacy((int) $params['id'], $this->adminId, $this->adminInfo);
|
||||
|
||||
if ($result === false) {
|
||||
$error = PrescriptionOrderLogic::getError();
|
||||
\think\facade\Log::error('submitGancaoRecipel failed', ['error' => $error, 'params' => $params]);
|
||||
return $this->fail($error);
|
||||
}
|
||||
|
||||
// 确保返回的数据是可序列化的
|
||||
if (!is_array($result)) {
|
||||
\think\facade\Log::error('submitGancaoRecipel result is not array', ['result' => $result]);
|
||||
return $this->fail('返回数据格式错误');
|
||||
}
|
||||
|
||||
return $this->success('药方上传成功', $result);
|
||||
} catch (\Throwable $e) {
|
||||
\think\facade\Log::error('submitGancaoRecipel exception', [
|
||||
'message' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
return $this->fail('系统错误:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unified pharmacy upload. The order ship_mode decides the target.
|
||||
*/
|
||||
public function uploadToPharmacy()
|
||||
{
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('uploadToPharmacy');
|
||||
$result = PrescriptionOrderLogic::uploadToPharmacy((int) $params['id'], $this->adminId, $this->adminInfo);
|
||||
if ($result === false) {
|
||||
return $this->fail(PrescriptionOrderLogic::getError());
|
||||
}
|
||||
return $this->success('药方上传成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 甘草药管家:预下单测试(仅 CTM_PREVIEW,不提交订单)
|
||||
* 用于在编辑订单时测试价格和配置
|
||||
*/
|
||||
public function previewGancaoRecipel()
|
||||
{
|
||||
try {
|
||||
$params = (new PrescriptionOrderValidate())->post()->goCheck('previewGancaoRecipel');
|
||||
$result = PrescriptionOrderLogic::previewGancaoRecipel((int) $params['id'], $this->adminId, $this->adminInfo, $params);
|
||||
|
||||
if ($result === false) {
|
||||
$error = PrescriptionOrderLogic::getError();
|
||||
\think\facade\Log::error('previewGancaoRecipel failed', ['error' => $error, 'params' => $params]);
|
||||
return $this->fail($error);
|
||||
}
|
||||
|
||||
return $this->success('预下单成功', $result);
|
||||
} catch (\Throwable $e) {
|
||||
\think\facade\Log::error('previewGancaoRecipel exception', [
|
||||
'message' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine()
|
||||
]);
|
||||
return $this->fail('系统错误:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user