From 64d760af1a2af4aad6febb6935af5f2d8cfc594c Mon Sep 17 00:00:00 2001
From: long <452591453@qq.com>
Date: Tue, 28 Jul 2026 16:28:36 +0800
Subject: [PATCH] debug
---
.../src/views/consumer/prescription/index.vue | 7 +++++-
.../logic/tcm/PrescriptionOrderLogic.php | 24 ++++++++++++++++++-
.../EjPharmacyCallbackController.php | 2 +-
.../pharmacy/EjPharmacyShipmentPolicy.php | 19 ++++++++++++---
.../pharmacy/callback_auth_integration.php | 9 ++++---
5 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/admin/src/views/consumer/prescription/index.vue b/admin/src/views/consumer/prescription/index.vue
index 3bb92825..e2ac0db7 100644
--- a/admin/src/views/consumer/prescription/index.vue
+++ b/admin/src/views/consumer/prescription/index.vue
@@ -1304,7 +1304,7 @@
-
+
甘草药房
@@ -1715,6 +1715,7 @@ import { roleAll } from '@/api/perms/role'
import { usePaging } from '@/hooks/usePaging'
import useUserStore from '@/stores/modules/user'
import feedback from '@/utils/feedback'
+import { hasPermission } from '@/utils/perm'
import type { FormInstance, FormRules } from 'element-plus'
import DaterangePicker from '@/components/daterange-picker/index.vue'
import MedicineNameSelect from '@/components/medicine-name-select/index.vue'
@@ -2037,6 +2038,10 @@ const createOrderForm = reactive({
pay_order_ids: [] as number[]
})
+// 只有具备「设置发货类型」权限的账号才可在创建业务订单时选择洛阳药房;
+// 无权限账号保持历史默认逻辑,固定走甘草药房。
+const canSelectShipMode = computed(() => hasPermission(['tcm.prescriptionOrder/setShipMode']))
+
// 省市区数据(简化版,实际项目中应该从 API 获取或使用完整的省市区数据)
const regionOptions = ref([])
diff --git a/server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php b/server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php
index 1e1129e1..72ed42a6 100755
--- a/server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php
+++ b/server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php
@@ -343,6 +343,21 @@ class PrescriptionOrderLogic
return false;
}
+ /**
+ * 是否允许在业务订单中选择发货药房(甘草 / 洛阳)。
+ * 无此权限时沿用历史逻辑,订单固定走甘草药房。
+ */
+ public static function canSelectShipMode(array $adminInfo): bool
+ {
+ if (!empty($adminInfo['root']) && (int) $adminInfo['root'] === 1) {
+ return true;
+ }
+
+ $permissions = AuthLogic::getAuthByAdminId((int) ($adminInfo['admin_id'] ?? 0));
+
+ return in_array('tcm.prescriptionOrder/setShipMode', $permissions, true);
+ }
+
/**
* @param PrescriptionOrder $row
*/
@@ -1022,7 +1037,9 @@ class PrescriptionOrderLogic
$order->service_package = (string) ($params['service_package'] ?? '');
$order->tracking_number = (string) ($params['tracking_number'] ?? '');
$order->express_company = self::normalizeExpressCompany($params['express_company'] ?? 'auto');
- $order->ship_mode = self::normalizeShipMode((string) ($params['ship_mode'] ?? 'gancao'));
+ $order->ship_mode = self::canSelectShipMode($adminInfo)
+ ? self::normalizeShipMode((string) ($params['ship_mode'] ?? 'gancao'))
+ : 'gancao';
$order->fee_type = (int) $params['fee_type'];
$order->amount = round((float) $params['amount'], 2);
$order->internal_cost = $internalCost;
@@ -5132,6 +5149,11 @@ class PrescriptionOrderLogic
return false;
}
+ if (!self::canSelectShipMode($adminInfo)) {
+ self::$error = '无权限设置发货药房';
+
+ return false;
+ }
if (!self::assertRemoteSnapshotMutable($order)) {
return false;
}
diff --git a/server/app/api/controller/EjPharmacyCallbackController.php b/server/app/api/controller/EjPharmacyCallbackController.php
index 110ebcd0..90200b4d 100644
--- a/server/app/api/controller/EjPharmacyCallbackController.php
+++ b/server/app/api/controller/EjPharmacyCallbackController.php
@@ -244,7 +244,7 @@ class EjPharmacyCallbackController extends BaseApiController
// Keep the same readable production-flow format as Gancao:
// flow name and pharmacy are the primary information.
$summaryParts = [
- '洛阳药房回传:' . (EjPharmacyShipmentPolicy::isCompletedEvent($payload) ? '订单已完成' : '订单药房流转制作中'),
+ '洛阳药房回传:订单药房流转制作中',
'流程:' . $stepName,
'药房:洛阳药房',
];
diff --git a/server/app/common/service/pharmacy/EjPharmacyShipmentPolicy.php b/server/app/common/service/pharmacy/EjPharmacyShipmentPolicy.php
index 1211f5fb..1ae1ce5c 100644
--- a/server/app/common/service/pharmacy/EjPharmacyShipmentPolicy.php
+++ b/server/app/common/service/pharmacy/EjPharmacyShipmentPolicy.php
@@ -13,12 +13,19 @@ final class EjPharmacyShipmentPolicy
|| strtoupper(trim((string) ($payload['status'] ?? ''))) === 'SHIPPED';
}
+ /** @param array $payload */
+ public static function isWorkflowStepEvent(array $payload): bool
+ {
+ return strtoupper(trim((string) ($payload['event_type'] ?? ''))) === 'WORKFLOW_STEP_COMPLETED';
+ }
+
/** @param array $payload */
public static function isCompletedEvent(array $payload): bool
{
- return strtoupper(trim((string) ($payload['status'] ?? ''))) === 'COMPLETED'
- || (strtoupper(trim((string) ($payload['event_type'] ?? ''))) === 'WORKFLOW_STEP_COMPLETED'
- && (bool) ($payload['final'] ?? false));
+ // A workflow node (including the final “ship” node) is only a
+ // pharmacy-process update. It must not close the ZYT business order.
+ return !self::isWorkflowStepEvent($payload)
+ && strtoupper(trim((string) ($payload['status'] ?? ''))) === 'COMPLETED';
}
/** @param array $payload */
@@ -47,6 +54,12 @@ final class EjPharmacyShipmentPolicy
? $rollbackStatus
: ($currentStatus === 9 ? 2 : $currentStatus);
}
+ if (self::isWorkflowStepEvent($payload)) {
+ // EJ workflow callbacks are informational nodes. Keep the ZYT
+ // fulfillment status unchanged; only explicit shipment/completion
+ // events may advance it.
+ return $currentStatus;
+ }
if (self::isShippedEvent($payload) && in_array($currentStatus, [1, 2], true)) {
return 5;
}
diff --git a/server/tests/pharmacy/callback_auth_integration.php b/server/tests/pharmacy/callback_auth_integration.php
index 2fb5288b..163cf3b1 100644
--- a/server/tests/pharmacy/callback_auth_integration.php
+++ b/server/tests/pharmacy/callback_auth_integration.php
@@ -235,17 +235,17 @@ $assertSame(
'non-shipment callbacks must not change local fulfillment'
);
$assertSame(
- true,
+ false,
EjPharmacyShipmentPolicy::isCompletedEvent(['event_type' => 'WORKFLOW_STEP_COMPLETED', 'status' => 'COMPLETED', 'final' => true]),
- 'a final EJ workflow callback must be recognized as order completion'
+ 'a final EJ workflow callback must remain a process update, not order completion'
);
$assertSame(
- 3,
+ 2,
EjPharmacyShipmentPolicy::nextFulfillmentStatus(
2,
['event_type' => 'WORKFLOW_STEP_COMPLETED', 'status' => 'COMPLETED', 'final' => true]
),
- 'a final EJ workflow callback must advance ZYT fulfillment to completed'
+ 'a final EJ workflow callback must not change ZYT fulfillment'
);
$assertSame(
2,
@@ -424,7 +424,6 @@ $assertSame(
$assertSame(
true,
str_contains($controllerSource, '订单药房流转制作中')
- && str_contains($controllerSource, '订单已完成')
&& str_contains($controllerSource, '流程:')
&& str_contains($controllerSource, '药房:洛阳药房')
&& str_contains($controllerSource, "implode(\$isWorkflowStep ? ' | ' : ';', \$summaryParts)"),