Merge branch '20260604-long'
This commit is contained in:
@@ -207,6 +207,11 @@ class OrderController extends BaseAdminController
|
||||
$params['creator_id'] = $this->adminId;
|
||||
$params['payment_channel'] = (string)$this->request->post('payment_channel', 'normal');
|
||||
$params['require_payment_slip_audit'] = (int)$this->request->post('require_payment_slip_audit', 0);
|
||||
// 创建方式:优先取前端透传的 create_type,否则按 payment_channel 派生(fubei→fubei,其余 normal)
|
||||
$createTypeReq = (string)$this->request->post('create_type', '');
|
||||
$params['create_type'] = in_array($createTypeReq, ['normal', 'wechat_work', 'fubei'], true)
|
||||
? $createTypeReq
|
||||
: ($params['payment_channel'] === 'fubei' ? 'fubei' : 'normal');
|
||||
|
||||
$result = OrderLogic::create($params);
|
||||
if (!$result) {
|
||||
@@ -227,6 +232,7 @@ class OrderController extends BaseAdminController
|
||||
{
|
||||
$params = (new OrderValidate())->post()->goCheck('create');
|
||||
$params['creator_id'] = $this->adminId;
|
||||
$params['create_type'] = 'wechat_work';
|
||||
|
||||
$result = OrderLogic::createForWechatWork($params);
|
||||
if (!$result) {
|
||||
|
||||
@@ -22,6 +22,11 @@ use think\facade\Log;
|
||||
*/
|
||||
class OrderLogic
|
||||
{
|
||||
/**
|
||||
* 创建方式统一三值:normal 普通订单 / wechat_work 企业微信对外收款 / fubei 付呗
|
||||
*/
|
||||
private const CREATE_TYPES = ['normal', 'wechat_work', 'fubei'];
|
||||
|
||||
/**
|
||||
* @notes 生成订单号
|
||||
* @return string
|
||||
@@ -31,6 +36,34 @@ class OrderLogic
|
||||
return 'ORD' . date('YmdHis') . mt_rand(100000, 999999);
|
||||
}
|
||||
|
||||
private static function normalizeCreateType(
|
||||
?string $createType,
|
||||
?string $paymentMethod = null,
|
||||
?string $payeeUserid = null,
|
||||
?string $payerExternalUserid = null,
|
||||
?string $remark = null
|
||||
): string {
|
||||
$raw = trim((string) $createType);
|
||||
if (in_array($raw, self::CREATE_TYPES, true)) {
|
||||
return $raw;
|
||||
}
|
||||
|
||||
$paymentMethod = trim((string) $paymentMethod);
|
||||
if ($paymentMethod === 'fubei') {
|
||||
return 'fubei';
|
||||
}
|
||||
|
||||
if (
|
||||
trim((string) $payeeUserid) !== ''
|
||||
|| trim((string) $payerExternalUserid) !== ''
|
||||
|| str_contains((string) $remark, '企业微信')
|
||||
) {
|
||||
return 'wechat_work';
|
||||
}
|
||||
|
||||
return 'normal';
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 创建订单
|
||||
* @param array $params
|
||||
@@ -43,6 +76,8 @@ class OrderLogic
|
||||
if (!in_array($channel, ['normal', 'fubei'], true)) {
|
||||
$channel = 'normal';
|
||||
}
|
||||
$paymentMethod = $channel === 'fubei' ? 'fubei' : null;
|
||||
$createType = self::normalizeCreateType((string)($params['create_type'] ?? ''), $paymentMethod);
|
||||
$requirePaymentSlipAudit = (int)($params['require_payment_slip_audit'] ?? 0) === 1;
|
||||
|
||||
$order = new Order();
|
||||
@@ -51,6 +86,7 @@ class OrderLogic
|
||||
$order->creator_id = $params['creator_id'];
|
||||
$order->order_type = $params['order_type'];
|
||||
$order->amount = $params['amount'];
|
||||
$order->create_type = $createType;
|
||||
// 付呗且申请审核支付单:待审核(5);否则待支付(1)
|
||||
if ($channel === 'fubei') {
|
||||
$order->payment_method = 'fubei';
|
||||
@@ -183,6 +219,10 @@ class OrderLogic
|
||||
$order->payment_method = 'wechat';
|
||||
$needSave = true;
|
||||
}
|
||||
if ((string) ($order->create_type ?? '') !== 'wechat_work') {
|
||||
$order->create_type = 'wechat_work';
|
||||
$needSave = true;
|
||||
}
|
||||
if ($paymentTimeStr !== '' && (string)$order->payment_time !== $paymentTimeStr) {
|
||||
$order->payment_time = $paymentTimeStr;
|
||||
$needSave = true;
|
||||
@@ -235,6 +275,7 @@ class OrderLogic
|
||||
$order->amount = $amount;
|
||||
$order->status = $targetStatus;
|
||||
$order->payment_method = 'wechat';
|
||||
$order->create_type = 'wechat_work';
|
||||
$order->payment_time = $paymentTimeStr;
|
||||
$order->trade_no = $tradeNo;
|
||||
$remark = '企业微信直接收款同步,待关联患者';
|
||||
@@ -283,6 +324,7 @@ class OrderLogic
|
||||
$order->amount = $amount;
|
||||
$order->status = 2; // 已支付
|
||||
$order->payment_method = 'wechat';
|
||||
$order->create_type = 'wechat_work';
|
||||
$order->payment_time = date('Y-m-d H:i:s');
|
||||
$order->trade_no = $tradeNo;
|
||||
$order->remark = '企业微信直接收款,待关联患者';
|
||||
@@ -536,6 +578,13 @@ class OrderLogic
|
||||
$n->creator_id = $order->creator_id;
|
||||
$n->order_type = (int) $typeList[$i];
|
||||
$n->amount = $amt;
|
||||
$n->create_type = self::normalizeCreateType(
|
||||
(string) ($order->create_type ?? ''),
|
||||
(string) ($order->payment_method ?? ''),
|
||||
(string) ($order->payee_userid ?? ''),
|
||||
(string) ($order->payer_external_userid ?? ''),
|
||||
(string) ($order->remark ?? '')
|
||||
);
|
||||
if ($st === 5) {
|
||||
$n->payment_method = 'fubei';
|
||||
$n->status = 5;
|
||||
@@ -1213,7 +1262,7 @@ class OrderLogic
|
||||
}
|
||||
|
||||
$rows = $q
|
||||
->field(['id', 'order_no', 'order_type', 'amount', 'status', 'create_time', 'creator_id', 'remark', 'is_exempt'])
|
||||
->field(['id', 'order_no', 'order_type', 'amount', 'status', 'create_time', 'creator_id', 'remark', 'is_exempt', 'payment_method', 'create_type'])
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
@@ -696,6 +696,8 @@ class PrescriptionOrderLogic
|
||||
{
|
||||
PrescriptionOrderPayOrder::where('prescription_order_id', (int) $order->id)->delete();
|
||||
$order->linked_pay_order_id = null;
|
||||
// 解除关联后刷新「需代收」固定快照(已付归零 → 需代收=总金额)
|
||||
self::refreshAgencyCollectSnapshot((int) $order->id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -768,7 +770,7 @@ class PrescriptionOrderLogic
|
||||
return [];
|
||||
}
|
||||
$rows = Order::whereIn('id', $ids)->whereNull('delete_time')
|
||||
->field(['id', 'order_no', 'order_type', 'amount', 'status', 'create_time', 'creator_id', 'remark', 'is_exempt'])
|
||||
->field(['id', 'order_no', 'order_type', 'amount', 'status', 'create_time', 'creator_id', 'remark', 'is_exempt', 'payment_method', 'create_type'])
|
||||
->order('id', 'asc')
|
||||
->whereIn('status', [2, 4, 5])
|
||||
->select()
|
||||
@@ -837,6 +839,35 @@ class PrescriptionOrderLogic
|
||||
$arr['deposit_min_amount'] = self::depositMinAmount();
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新「需代收」固定快照:按当前 总金额 − 关联已付总额(支付单 status ∈ {2 已支付, 5 待审核})写入 agency_collect_amount。
|
||||
* 在关联/新增支付单、建单、改总金额、解除关联等写操作末尾调用;之后退款/审核状态变化不再影响该值。
|
||||
*/
|
||||
private static function refreshAgencyCollectSnapshot(int $id): void
|
||||
{
|
||||
if ($id <= 0) {
|
||||
return;
|
||||
}
|
||||
$order = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
|
||||
if (!$order) {
|
||||
return;
|
||||
}
|
||||
$amount = round((float) $order->amount, 2);
|
||||
$paid = 0.0;
|
||||
$ids = self::linkedPayOrderIdList($id);
|
||||
if ($ids !== []) {
|
||||
$payOrders = Order::whereIn('id', $ids)->whereNull('delete_time')->field(['amount', 'status'])->select();
|
||||
foreach ($payOrders as $po) {
|
||||
$st = (int) $po->status;
|
||||
if ($st === 2 || $st === 5) {
|
||||
$paid += (float) $po->amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
$order->agency_collect_amount = round($amount - $paid, 2);
|
||||
$order->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $params
|
||||
* @return array<string,mixed>|false
|
||||
@@ -969,7 +1000,9 @@ class PrescriptionOrderLogic
|
||||
self::replacePayOrderLinks((int) $order->id, $payOrderIds);
|
||||
}
|
||||
|
||||
$out = $order->toArray();
|
||||
self::refreshAgencyCollectSnapshot((int) $order->id);
|
||||
|
||||
$out = PrescriptionOrder::where('id', (int) $order->id)->find()->toArray();
|
||||
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||
self::maskRemarkExtraIfNeeded($out, $adminInfo);
|
||||
self::attachLinkedPayOrders($out);
|
||||
@@ -1737,7 +1770,9 @@ class PrescriptionOrderLogic
|
||||
|
||||
self::writeLog((int) $order->id, $adminId, $adminInfo, 'edit', '编辑了业务订单及相关信息');
|
||||
|
||||
$out = $order->toArray();
|
||||
self::refreshAgencyCollectSnapshot((int) $order->id);
|
||||
|
||||
$out = PrescriptionOrder::where('id', (int) $order->id)->find()->toArray();
|
||||
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||
self::maskRemarkExtraIfNeeded($out, $adminInfo);
|
||||
self::attachLinkedPayOrders($out);
|
||||
@@ -2281,12 +2316,16 @@ class PrescriptionOrderLogic
|
||||
$order->payment_slip_audit_remark = '';
|
||||
self::syncFulfillmentStatus($order);
|
||||
|
||||
// 将关联的已支付支付单(status=2,且payment_method='manual')恢复为待审核(status=5)
|
||||
// 将关联的已支付补齐支付单恢复为待审核:兼容旧 manual 与新 fubei/create_type=fubei 两种标记
|
||||
$payOrderIds = self::linkedPayOrderIdList($id);
|
||||
if (!empty($payOrderIds)) {
|
||||
Order::whereIn('id', $payOrderIds)
|
||||
->where('status', 2) // 只恢复已支付状态的
|
||||
->where('payment_method', 'manual') // 只恢复手动创建的
|
||||
->where(function ($query) {
|
||||
$query->where('payment_method', 'manual')
|
||||
->whereOr('payment_method', 'fubei')
|
||||
->whereOr('create_type', 'fubei');
|
||||
})
|
||||
->update([
|
||||
'status' => 5, // 待审核
|
||||
'payment_time' => null
|
||||
@@ -2378,7 +2417,8 @@ class PrescriptionOrderLogic
|
||||
$payOrder->order_type = $orderType;
|
||||
$payOrder->amount = $amount;
|
||||
$payOrder->status = 5; // 待审核
|
||||
$payOrder->payment_method = 'manual';
|
||||
$payOrder->payment_method = 'fubei'; // 补齐支付单按「付呗」记账
|
||||
$payOrder->create_type = 'fubei';
|
||||
$payOrder->payment_time = null; // 审核通过后再设置支付时间
|
||||
$payOrder->remark = $remark;
|
||||
|
||||
@@ -2420,7 +2460,9 @@ class PrescriptionOrderLogic
|
||||
}
|
||||
self::writeLog($id, $adminId, $adminInfo, 'add_pay_order', $logMsg);
|
||||
|
||||
$out = $order->toArray();
|
||||
self::refreshAgencyCollectSnapshot($id);
|
||||
|
||||
$out = PrescriptionOrder::where('id', $id)->find()->toArray();
|
||||
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||
self::maskRemarkExtraIfNeeded($out, $adminInfo);
|
||||
self::attachLinkedPayOrders($out);
|
||||
@@ -2531,7 +2573,9 @@ class PrescriptionOrderLogic
|
||||
}
|
||||
self::writeLog($id, $adminId, $adminInfo, 'link_pay_order', $logMsg);
|
||||
|
||||
$out = $order->toArray();
|
||||
self::refreshAgencyCollectSnapshot($id);
|
||||
|
||||
$out = PrescriptionOrder::where('id', $id)->find()->toArray();
|
||||
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||
self::maskRemarkExtraIfNeeded($out, $adminInfo);
|
||||
self::attachLinkedPayOrders($out);
|
||||
@@ -3415,7 +3459,11 @@ class PrescriptionOrderLogic
|
||||
$item['export_refund_amount'] = $refundStored > 0
|
||||
? number_format($refundStored, 2, '.', '')
|
||||
: '';
|
||||
$item['export_agency_collect'] = number_format(round($amt - $paid, 2), 2, '.', '');
|
||||
// 需代收:优先用固定快照值 agency_collect_amount;历史单为 NULL 时回退实时 amt − paid
|
||||
$agencySnap = $item['agency_collect_amount'] ?? null;
|
||||
$item['export_agency_collect'] = ($agencySnap !== null && $agencySnap !== '')
|
||||
? number_format(round((float) $agencySnap, 2), 2, '.', '')
|
||||
: number_format(round($amt - $paid, 2), 2, '.', '');
|
||||
|
||||
$item['export_tracking_number'] = (string) ($item['tracking_number'] ?? '');
|
||||
$signTs = $poId > 0 ? (int) ($signTsByPoId[$poId] ?? 0) : 0;
|
||||
@@ -4149,6 +4197,9 @@ class PrescriptionOrderLogic
|
||||
return false;
|
||||
}
|
||||
|
||||
// 总金额变化后刷新「需代收」固定快照,保持与新总额一致
|
||||
self::refreshAgencyCollectSnapshot($id);
|
||||
|
||||
// 记录日志
|
||||
$summary = sprintf('将订单金额从 ¥%.2f 修改为 ¥%.2f', $oldAmount, $newAmount);
|
||||
self::writeLog($id, $adminId, $adminInfo, 'update_amount', $summary);
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- 支付单:创建方式(统一为三值,用于支付方式显示)
|
||||
ALTER TABLE `zyt_order`
|
||||
ADD COLUMN `create_type` varchar(20) NOT NULL DEFAULT 'normal' COMMENT '创建方式:normal 普通订单 / wechat_work 企业微信对外收款 / fubei 付呗' AFTER `payment_method`;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- 处方业务订单:需代收固定值(关联支付单/改总金额时快照,NULL 表示按实时计算回退)
|
||||
ALTER TABLE `zyt_tcm_prescription_order`
|
||||
ADD COLUMN `agency_collect_amount` decimal(10,2) DEFAULT NULL COMMENT '需代收固定值(关联/改额时快照,NULL 表示按实时计算回退)' AFTER `refund_amount`;
|
||||
Reference in New Issue
Block a user