订单
This commit is contained in:
@@ -263,4 +263,66 @@ class PrescriptionOrderController extends BaseAdminController
|
||||
|
||||
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::submitGancaoRecipel((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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 甘草药管家:预下单测试(仅 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ use app\common\model\Order;
|
||||
use app\common\model\tcm\Diagnosis;
|
||||
use app\common\model\tcm\PrescriptionOrder;
|
||||
use app\common\model\tcm\PrescriptionOrderPayOrder;
|
||||
use app\common\service\gancao\GancaoScmRecipelService;
|
||||
|
||||
class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchInterface, ListsExtendInterface
|
||||
{
|
||||
@@ -119,6 +120,11 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
}
|
||||
|
||||
$depMin = PrescriptionOrderLogic::depositMinAmount();
|
||||
$diagIdsForAssist = array_values(array_unique(array_filter(array_map('intval', array_column($lists, 'diagnosis_id')))));
|
||||
$assistantByDiag = [];
|
||||
if ($diagIdsForAssist !== []) {
|
||||
$assistantByDiag = Diagnosis::whereIn('id', $diagIdsForAssist)->whereNull('delete_time')->column('assistant_id', 'id');
|
||||
}
|
||||
foreach ($lists as &$item) {
|
||||
PrescriptionOrderLogic::maskInternalCostIfNeeded($item, $this->adminInfo);
|
||||
$pid = (int) ($item['id'] ?? 0);
|
||||
@@ -128,6 +134,12 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
)->count();
|
||||
$item['linked_pay_paid_total'] = $paidSumByPo[$pid] ?? 0.0;
|
||||
$item['deposit_min_amount'] = $depMin;
|
||||
$item['can_upload_gancao_reciperl'] = PrescriptionOrderLogic::canUploadGancaoRecipel(
|
||||
$item,
|
||||
$this->adminId,
|
||||
$this->adminInfo,
|
||||
$assistantByDiag
|
||||
);
|
||||
|
||||
// 添加创建人姓名
|
||||
$creatorId = (int) ($item['creator_id'] ?? 0);
|
||||
@@ -146,6 +158,7 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
{
|
||||
return [
|
||||
'deposit_min_amount' => PrescriptionOrderLogic::depositMinAmount(),
|
||||
'gancao_scm_enabled' => GancaoScmRecipelService::isConfigured(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -227,6 +227,9 @@ class PrescriptionLogic
|
||||
'sn' => $sn,
|
||||
'prescription_name' => $params['prescription_name'] ?? '',
|
||||
'prescription_type' => $params['prescription_type'] ?? '浓缩水丸',
|
||||
'dosage_amount' => isset($params['dosage_amount']) ? (float)$params['dosage_amount'] : null,
|
||||
'dosage_unit' => $params['dosage_unit'] ?? '',
|
||||
'need_decoction' => (int)($params['need_decoction'] ?? 0),
|
||||
'diagnosis_id' => (int)($params['diagnosis_id'] ?? 0),
|
||||
'appointment_id' => (int)($params['appointment_id'] ?? 0),
|
||||
'patient_id' => (int)($params['patient_id'] ?? 0),
|
||||
@@ -246,6 +249,7 @@ class PrescriptionLogic
|
||||
'dose_count' => (int)($params['dose_count'] ?? 1),
|
||||
'dose_unit' => $params['dose_unit'] ?? '剂',
|
||||
'usage_days' => (int)($params['usage_days'] ?? 7),
|
||||
'times_per_day' => (int)($params['times_per_day'] ?? 2),
|
||||
'usage_instruction' => $params['usage_instruction'] ?? '水煎服一日二次',
|
||||
'usage_time' => $params['usage_time'] ?? '饭前',
|
||||
'usage_way' => $params['usage_way'] ?? '温水送服',
|
||||
@@ -351,6 +355,9 @@ class PrescriptionLogic
|
||||
'assistant_id' => $assistantIdForRx,
|
||||
'prescription_name' => $params['prescription_name'] ?? $prescription->prescription_name,
|
||||
'prescription_type' => $params['prescription_type'] ?? $prescription->prescription_type,
|
||||
'dosage_amount' => isset($params['dosage_amount']) ? (float)$params['dosage_amount'] : $prescription->dosage_amount,
|
||||
'dosage_unit' => $params['dosage_unit'] ?? $prescription->dosage_unit,
|
||||
'need_decoction' => isset($params['need_decoction']) ? (int)$params['need_decoction'] : (int)($prescription->need_decoction ?? 0),
|
||||
'patient_name' => $params['patient_name'] ?? $prescription->patient_name,
|
||||
'gender' => (int)($params['gender'] ?? $prescription->gender),
|
||||
'age' => (int)($params['age'] ?? $prescription->age),
|
||||
@@ -365,6 +372,7 @@ class PrescriptionLogic
|
||||
'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),
|
||||
'times_per_day' => (int)($params['times_per_day'] ?? $prescription->times_per_day ?? 2),
|
||||
'usage_instruction' => $params['usage_instruction'] ?? $prescription->usage_instruction,
|
||||
'usage_time' => $params['usage_time'] ?? $prescription->usage_time,
|
||||
'usage_way' => $params['usage_way'] ?? $prescription->usage_way,
|
||||
|
||||
@@ -14,7 +14,9 @@ use app\common\model\tcm\PrescriptionOrderLog;
|
||||
use app\common\model\tcm\PrescriptionOrderPayOrder;
|
||||
use app\common\model\auth\Admin;
|
||||
use app\common\service\ExpressTrackService;
|
||||
use app\common\service\gancao\GancaoScmRecipelService;
|
||||
use think\facade\Config;
|
||||
use think\facade\Log;
|
||||
|
||||
class PrescriptionOrderLogic
|
||||
{
|
||||
@@ -672,9 +674,23 @@ class PrescriptionOrderLogic
|
||||
|
||||
$order->recipient_name = (string) $params['recipient_name'];
|
||||
$order->recipient_phone = (string) $params['recipient_phone'];
|
||||
|
||||
// 处理省市区字段
|
||||
if (isset($params['shipping_province'])) {
|
||||
$order->shipping_province = (string) $params['shipping_province'];
|
||||
}
|
||||
if (isset($params['shipping_city'])) {
|
||||
$order->shipping_city = (string) $params['shipping_city'];
|
||||
}
|
||||
if (isset($params['shipping_district'])) {
|
||||
$order->shipping_district = (string) $params['shipping_district'];
|
||||
}
|
||||
|
||||
$order->shipping_address = (string) $params['shipping_address'];
|
||||
$order->is_follow_up = (int) ($params['is_follow_up'] ?? 0) === 1 ? 1 : 0;
|
||||
$order->medication_days = $medDays > 0 ? $medDays : null;
|
||||
$order->dose_unit = (string) ($params['dose_unit'] ?? '剂');
|
||||
$order->dose_count = isset($params['dose_count']) && (int)$params['dose_count'] > 0 ? (int)$params['dose_count'] : 1;
|
||||
$order->prev_staff = (string) ($params['prev_staff'] ?? '');
|
||||
$order->service_channel = (string) ($params['service_channel'] ?? '');
|
||||
$order->service_package = (string) ($params['service_package'] ?? '');
|
||||
@@ -1154,6 +1170,28 @@ class PrescriptionOrderLogic
|
||||
return false;
|
||||
}
|
||||
|
||||
// 同步撤回处方表的审核状态
|
||||
$prescriptionId = (int) $order->prescription_id;
|
||||
if ($prescriptionId > 0) {
|
||||
try {
|
||||
$prescription = Prescription::where('id', $prescriptionId)->whereNull('delete_time')->find();
|
||||
if ($prescription) {
|
||||
$prescription->audit_status = 0;
|
||||
$prescription->audit_remark = '';
|
||||
$prescription->audit_time = null;
|
||||
$prescription->audit_by = null;
|
||||
$prescription->audit_by_name = '';
|
||||
$prescription->save();
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// 记录日志但不影响主流程
|
||||
Log::error('撤回处方审核时同步处方表失败: ' . $e->getMessage(), [
|
||||
'prescription_id' => $prescriptionId,
|
||||
'order_id' => $id
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
self::writeLog((int) $order->id, $adminId, $adminInfo, 'revoke_rx_audit', '撤回处方审核,状态重置为待审核');
|
||||
|
||||
$out = $order->toArray();
|
||||
@@ -1478,7 +1516,17 @@ class PrescriptionOrderLogic
|
||||
return false;
|
||||
}
|
||||
|
||||
// 计算关联订单总额
|
||||
$linkedPayOrderIds = self::linkedPayOrderIdList($id);
|
||||
$linkedPayOrders = self::linkedPayOrdersPayload($linkedPayOrderIds);
|
||||
$linkedPayPaidTotal = 0.0;
|
||||
foreach ($linkedPayOrders as $o) {
|
||||
$linkedPayPaidTotal += (float) ($o['amount'] ?? 0);
|
||||
}
|
||||
$linkedPayPaidTotal = round($linkedPayPaidTotal, 2);
|
||||
|
||||
$order->fulfillment_status = 3;
|
||||
$order->paid = $linkedPayPaidTotal;
|
||||
|
||||
try {
|
||||
$order->save();
|
||||
@@ -1487,7 +1535,7 @@ class PrescriptionOrderLogic
|
||||
return false;
|
||||
}
|
||||
|
||||
self::writeLog($id, $adminId, $adminInfo, 'complete', '订单完成,状态变更为「已完成」');
|
||||
self::writeLog($id, $adminId, $adminInfo, 'complete', '订单完成,状态变更为「已完成」,实付金额更新为 ¥' . $linkedPayPaidTotal);
|
||||
|
||||
$out = $order->toArray();
|
||||
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||
@@ -1496,6 +1544,338 @@ class PrescriptionOrderLogic
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表行是否展示「上传甘草药方」(需配置甘草、处方审核通过、未上传过、有权限;不要求支付审核)。
|
||||
*
|
||||
* @param array<string,mixed> $item
|
||||
* @param array<int, int|string> $assistantByDiag diagnosis_id => assistant_id
|
||||
*/
|
||||
public static function canUploadGancaoRecipel(array $item, int $adminId, array $adminInfo, array $assistantByDiag = []): bool
|
||||
{
|
||||
if (!GancaoScmRecipelService::isConfigured()) {
|
||||
return false;
|
||||
}
|
||||
$pa = (int) ($item['prescription_audit_status'] ?? 0);
|
||||
$fs = (int) ($item['fulfillment_status'] ?? 0);
|
||||
if ($pa !== 1) {
|
||||
return false;
|
||||
}
|
||||
if ($fs === 3 || $fs === 4) {
|
||||
return false;
|
||||
}
|
||||
if (trim((string) ($item['gancao_reciperl_order_no'] ?? '')) !== '') {
|
||||
return false;
|
||||
}
|
||||
if (self::canSeeAllPrescriptionOrders($adminInfo)) {
|
||||
return true;
|
||||
}
|
||||
if ((int) ($item['creator_id'] ?? 0) === $adminId) {
|
||||
return true;
|
||||
}
|
||||
$did = (int) ($item['diagnosis_id'] ?? 0);
|
||||
$aid = (int) ($assistantByDiag[$did] ?? 0);
|
||||
|
||||
return $aid === $adminId && $adminId > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将当前业务订单关联处方提交至甘草药管家(CTM_PREVIEW → CTM_SUBMIT_RECIPEL)。
|
||||
*
|
||||
* @return array<string,mixed>|false 成功返回甘草 result 主要字段
|
||||
*/
|
||||
public static function submitGancaoRecipel(int $id, int $adminId, array $adminInfo)
|
||||
{
|
||||
|
||||
self::$error = '';
|
||||
if (!GancaoScmRecipelService::isConfigured()) {
|
||||
$why = GancaoScmRecipelService::whyNotConfigured();
|
||||
self::$error = $why !== '' ? $why : '甘草处方上传未启用或未配置完整,请检查 .env(GANCAO_SCM_*)须写在任意 [分区] 之前,或使用 [GANCAO_SCM] 分区';
|
||||
|
||||
return false;
|
||||
}
|
||||
$order = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
|
||||
if (!$order) {
|
||||
self::$error = '订单不存在';
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!self::canAccessOrder($order, $adminId, $adminInfo)) {
|
||||
self::$error = '无权限操作';
|
||||
|
||||
return false;
|
||||
}
|
||||
$item = $order->toArray();
|
||||
$assistantByDiag = Diagnosis::where('id', (int) $order->diagnosis_id)->whereNull('delete_time')->column('assistant_id', 'id');
|
||||
|
||||
if (!self::canUploadGancaoRecipel($item, $adminId, $adminInfo, $assistantByDiag)) {
|
||||
self::$error = '须处方审核通过后方可上传甘草;已完成/已取消订单不可上传;同一订单仅可上传一次';
|
||||
|
||||
return false;
|
||||
}
|
||||
$rxId = (int) $order->prescription_id;
|
||||
|
||||
if ($rxId <= 0) {
|
||||
self::$error = '订单未关联处方';
|
||||
|
||||
return false;
|
||||
}
|
||||
$rx = PrescriptionLogic::detail($rxId, $adminId, $adminInfo);
|
||||
if ($rx === null) {
|
||||
self::$error = PrescriptionLogic::getError() !== '' ? PrescriptionLogic::getError() : '处方不存在';
|
||||
|
||||
return false;
|
||||
}
|
||||
$c = Config::get('gancao_scm', []);
|
||||
$nameMap = is_array($c['herb_id_map'] ?? null) ? $c['herb_id_map'] : [];
|
||||
$herbs = is_array($rx['herbs'] ?? null) ? $rx['herbs'] : [];
|
||||
$docGidMap = GancaoScmRecipelService::doctorMedicineGidMapForHerbs($herbs);
|
||||
|
||||
[, $missing] = GancaoScmRecipelService::buildMList($herbs, $nameMap, $docGidMap);
|
||||
if ($missing !== []) {
|
||||
self::$error = '以下药材无法匹配甘草药ID(请核对医师药品库 zyt_doctor_medicine 中同名字段的 gid,或在处方 herbs 中写 gc_id / config 的 herb_id_map):' . implode('、', $missing);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$token = GancaoScmRecipelService::getToken(false);
|
||||
if ($token === null || $token === '') {
|
||||
$why = GancaoScmRecipelService::getLastGetTokenError();
|
||||
self::$error = $why !== '' ? $why : '获取甘草开放平台 token 失败,请检查 GANCAO_SCM_GATEWAY_*(网关 OpenAPI)与 GANCAO_SCM_BIZ_*(业务账号,常与网关不同)、网关地址及服务器时间';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$orderArr = $order->toArray();
|
||||
|
||||
// dump($rx);
|
||||
// dump($orderArr);
|
||||
$previewPayload = GancaoScmRecipelService::buildPreviewPayload($rx, $orderArr, $token);
|
||||
|
||||
$prevRet = GancaoScmRecipelService::ctmPreview($previewPayload);
|
||||
|
||||
if ((int) ($prevRet['state'] ?? 0) !== 1) {
|
||||
self::$error = '甘草预检查通信失败:' . (string) ($prevRet['msg'] ?? '');
|
||||
|
||||
return false;
|
||||
}
|
||||
$prevBody = $prevRet['body'] ?? [];
|
||||
|
||||
if (!GancaoScmRecipelService::isApiSuccess($prevBody)) {
|
||||
self::$error = '甘草预检查未通过:' . GancaoScmRecipelService::apiStatusMessage($prevBody);
|
||||
|
||||
return false;
|
||||
}
|
||||
$result = $prevBody['result'] ?? [];
|
||||
|
||||
if (is_array($result)) {
|
||||
$rules = $result['rule_check'] ?? [];
|
||||
if (is_array($rules)) {
|
||||
foreach ($rules as $ru) {
|
||||
if (!is_array($ru)) {
|
||||
continue;
|
||||
}
|
||||
$t = (int) ($ru['type'] ?? 0);
|
||||
if ($t >= 2) {
|
||||
self::$error = '甘草预检查规则拦截:' . (string) ($ru['msg'] ?? '') . '(code:' . (string) ($ru['code'] ?? '') . ')';
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
$mListOut = $result['m_list'] ?? [];
|
||||
if (is_array($mListOut)) {
|
||||
foreach ($mListOut as $rowM) {
|
||||
if (is_array($rowM) && isset($rowM['is_available']) && (int) $rowM['is_available'] === 0) {
|
||||
$tn = (string) ($rowM['title'] ?? '');
|
||||
self::$error = '甘草药库缺药,请调整处方:' . ($tn !== '' ? $tn : '未知药材');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$addrParts = GancaoScmRecipelService::splitCnAddress((string) $order->shipping_address);
|
||||
|
||||
$appNo = (string) $order->order_no;
|
||||
|
||||
$submitPayload = GancaoScmRecipelService::buildSubmitPayload($rx, $orderArr, $token, $addrParts, $appNo);
|
||||
|
||||
$subRet = GancaoScmRecipelService::ctmSubmit($submitPayload);
|
||||
|
||||
if ((int) ($subRet['state'] ?? 0) !== 1) {
|
||||
$errMsg = (string) ($subRet['msg'] ?? '');
|
||||
$response = isset($subRet['response']) ? mb_substr((string) $subRet['response'], 0, 500) : '';
|
||||
self::$error = '甘草下单通信失败:' . $errMsg . ($response !== '' ? ';响应:' . $response : '');
|
||||
Log::error('Gancao CTM_SUBMIT failed', [
|
||||
'subRet' => $subRet,
|
||||
'payload' => json_encode(GancaoScmRecipelService::maskSensitiveData($submitPayload), JSON_UNESCAPED_UNICODE)
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
$subBody = $subRet['body'] ?? [];
|
||||
|
||||
if (!GancaoScmRecipelService::isApiSuccess($subBody)) {
|
||||
self::$error = '甘草下单失败:' . GancaoScmRecipelService::apiStatusMessage($subBody);
|
||||
Log::error('Gancao CTM_SUBMIT api error', [
|
||||
'body' => $subBody,
|
||||
'payload' => json_encode(GancaoScmRecipelService::maskSensitiveData($submitPayload), JSON_UNESCAPED_UNICODE)
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
$gcNo = (string) (($subBody['result'] ?? [])['recipel_order_no'] ?? '');
|
||||
if ($gcNo === '') {
|
||||
self::$error = '甘草返回缺少 recipel_order_no';
|
||||
|
||||
return false;
|
||||
}
|
||||
$order->gancao_reciperl_order_no = mb_substr($gcNo, 0, 32);
|
||||
$order->gancao_submit_time = time();
|
||||
try {
|
||||
$order->save();
|
||||
} catch (\Throwable $e) {
|
||||
self::$error = '本地保存甘草单号失败:' . $e->getMessage();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
self::writeLog($id, $adminId, $adminInfo, 'gancao_submit', '上传甘草药方成功 ' . $gcNo);
|
||||
|
||||
$fee = $subBody['result']['fee'] ?? [];
|
||||
$appNo = $submitPayload['app_order_no'] ?? ('PO' . (string) $order->id);
|
||||
|
||||
return [
|
||||
'recipel_order_no' => $gcNo,
|
||||
'app_order_no' => $appNo,
|
||||
'fee' => is_array($fee) ? $fee : [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 甘草预下单测试(仅 CTM_PREVIEW,不提交订单)
|
||||
* 用于在编辑订单时测试价格和配置
|
||||
*
|
||||
* @param array $params 包含 id 和可选的 dose_count
|
||||
* @return array<string,mixed>|false 成功返回预览结果(包含价格信息)
|
||||
*/
|
||||
public static function previewGancaoRecipel(int $id, int $adminId, array $adminInfo, array $params = [])
|
||||
{
|
||||
self::$error = '';
|
||||
if (!GancaoScmRecipelService::isConfigured()) {
|
||||
$why = GancaoScmRecipelService::whyNotConfigured();
|
||||
self::$error = $why !== '' ? $why : '甘草处方上传未启用或未配置完整';
|
||||
return false;
|
||||
}
|
||||
|
||||
$order = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
|
||||
if (!$order) {
|
||||
self::$error = '订单不存在';
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!self::canAccessOrder($order, $adminId, $adminInfo)) {
|
||||
self::$error = '无权限操作';
|
||||
return false;
|
||||
}
|
||||
|
||||
$rxId = (int) $order->prescription_id;
|
||||
if ($rxId <= 0) {
|
||||
self::$error = '订单未关联处方';
|
||||
return false;
|
||||
}
|
||||
|
||||
$rx = PrescriptionLogic::detail($rxId, $adminId, $adminInfo);
|
||||
if ($rx === null) {
|
||||
self::$error = PrescriptionLogic::getError() !== '' ? PrescriptionLogic::getError() : '处方不存在';
|
||||
return false;
|
||||
}
|
||||
|
||||
$c = Config::get('gancao_scm', []);
|
||||
$nameMap = is_array($c['herb_id_map'] ?? null) ? $c['herb_id_map'] : [];
|
||||
$herbs = is_array($rx['herbs'] ?? null) ? $rx['herbs'] : [];
|
||||
$docGidMap = GancaoScmRecipelService::doctorMedicineGidMapForHerbs($herbs);
|
||||
|
||||
[, $missing] = GancaoScmRecipelService::buildMList($herbs, $nameMap, $docGidMap);
|
||||
if ($missing !== []) {
|
||||
self::$error = '以下药材无法匹配甘草药ID:' . implode('、', $missing);
|
||||
return false;
|
||||
}
|
||||
|
||||
$token = GancaoScmRecipelService::getToken(false);
|
||||
if ($token === null || $token === '') {
|
||||
$why = GancaoScmRecipelService::getLastGetTokenError();
|
||||
self::$error = $why !== '' ? $why : '获取甘草开放平台 token 失败';
|
||||
return false;
|
||||
}
|
||||
|
||||
$orderArr = $order->toArray();
|
||||
|
||||
// 如果传递了 dose_count 参数,使用传递的值覆盖订单中的值
|
||||
if (isset($params['dose_count']) && (int)$params['dose_count'] > 0) {
|
||||
$orderArr['dose_count'] = (int)$params['dose_count'];
|
||||
}
|
||||
|
||||
// 如果传递了 medication_days 参数,使用传递的值覆盖订单中的值
|
||||
if (isset($params['medication_days']) && (int)$params['medication_days'] > 0) {
|
||||
$orderArr['medication_days'] = (int)$params['medication_days'];
|
||||
}
|
||||
|
||||
$previewPayload = GancaoScmRecipelService::buildPreviewPayload($rx, $orderArr, $token);
|
||||
$prevRet = GancaoScmRecipelService::ctmPreview($previewPayload);
|
||||
|
||||
if ((int) ($prevRet['state'] ?? 0) !== 1) {
|
||||
self::$error = '甘草预检查通信失败:' . (string) ($prevRet['msg'] ?? '');
|
||||
return false;
|
||||
}
|
||||
|
||||
$prevBody = $prevRet['body'] ?? [];
|
||||
if (!GancaoScmRecipelService::isApiSuccess($prevBody)) {
|
||||
self::$error = '甘草预检查未通过:' . GancaoScmRecipelService::apiStatusMessage($prevBody);
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $prevBody['result'] ?? [];
|
||||
|
||||
// 检查规则拦截
|
||||
if (is_array($result)) {
|
||||
$rules = $result['rule_check'] ?? [];
|
||||
if (is_array($rules)) {
|
||||
foreach ($rules as $ru) {
|
||||
if (!is_array($ru)) continue;
|
||||
$t = (int) ($ru['type'] ?? 0);
|
||||
if ($t >= 2) {
|
||||
self::$error = '甘草预检查规则拦截:' . (string) ($ru['msg'] ?? '');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查药材可用性
|
||||
$mListOut = $result['m_list'] ?? [];
|
||||
if (is_array($mListOut)) {
|
||||
foreach ($mListOut as $rowM) {
|
||||
if (is_array($rowM) && isset($rowM['is_available']) && (int) $rowM['is_available'] === 0) {
|
||||
$tn = (string) ($rowM['title'] ?? '');
|
||||
self::$error = '甘草药库缺药:' . ($tn !== '' ? $tn : '未知药材');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 返回预览结果
|
||||
$fee = $result['fee'] ?? [];
|
||||
return [
|
||||
'success' => true,
|
||||
'fee' => is_array($fee) ? $fee : [],
|
||||
'result' => $result,
|
||||
'order_no' => (string) $order->order_no,
|
||||
'dose_count' => (int) ($orderArr['dose_count'] ?? $rx['dose_count'] ?? 0),
|
||||
];
|
||||
}
|
||||
|
||||
private static function writeLog(int $orderId, int $adminId, array $adminInfo, string $action, string $summary): void
|
||||
{
|
||||
$adminName = $adminInfo['name'] ?? '';
|
||||
|
||||
@@ -65,5 +65,7 @@ class PrescriptionOrderValidate extends BaseValidate
|
||||
'addPayOrder' => ['id', 'order_type', 'pay_amount', 'pay_remark'],
|
||||
'linkPayOrder' => ['id', 'pay_order_id'],
|
||||
'complete' => ['id'],
|
||||
'submitGancaoRecipel' => ['id'],
|
||||
'previewGancaoRecipel' => ['id'],
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user