From 34cad62c8e6e452732cbadc25571aec48439e60c Mon Sep 17 00:00:00 2001
From: luofei <604446095@qq.com>
Date: Tue, 4 Jun 2024 14:15:08 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=B4=A2=E5=8A=A1=E6=B5=81?=
 =?UTF-8?q?=E6=B0=B4=E3=80=81=E6=94=AF=E4=BB=98=E5=9B=9E=E8=B0=83=E3=80=81?=
 =?UTF-8?q?=E8=B5=84=E9=87=91=E6=B5=81=E6=B0=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/api/logic/order/OrderLogic.php            |   3 +
 app/common/logic/CapitalFlowLogic.php         | 154 ++++++++++++++++++
 app/common/logic/PayNotifyLogLogic.php        |  42 +++++
 app/common/logic/PayNotifyLogic.php           |  83 ++--------
 app/common/logic/StoreFinanceFlowLogic.php    |  75 +++++++++
 app/common/model/finance/CapitalFlow.php      |  10 ++
 app/common/model/finance/PayNotifyLog.php     |  13 ++
 .../store_order/StoreOrderController.php      |   2 +-
 8 files changed, 315 insertions(+), 67 deletions(-)
 create mode 100644 app/common/logic/CapitalFlowLogic.php
 create mode 100644 app/common/logic/PayNotifyLogLogic.php
 create mode 100644 app/common/logic/StoreFinanceFlowLogic.php
 create mode 100644 app/common/model/finance/CapitalFlow.php
 create mode 100644 app/common/model/finance/PayNotifyLog.php

diff --git a/app/api/logic/order/OrderLogic.php b/app/api/logic/order/OrderLogic.php
index a52eafcd8..6d004e1b2 100644
--- a/app/api/logic/order/OrderLogic.php
+++ b/app/api/logic/order/OrderLogic.php
@@ -6,6 +6,7 @@ use app\common\enum\OrderEnum;
 use app\common\enum\PayEnum;
 use app\common\enum\YesNoEnum;
 use app\common\logic\BaseLogic;
+use app\common\logic\CapitalFlowLogic;
 use app\common\model\merchant\Merchant;
 use app\common\model\order\Cart;
 use app\common\model\store_branch_product\StoreBranchProduct;
@@ -291,6 +292,8 @@ class OrderLogic extends BaseLogic
         try {
             $user->user_money = bcsub($user->user_money, $order['actual'], 2);
             $user->save();
+            $capitalFlowDao = new CapitalFlowLogic($user);
+            $capitalFlowDao->userExpense('user_order_pay', 'order', $order['id'], $order['actual']);
             Db::commit();
             return true;
         } catch (Exception $e) {
diff --git a/app/common/logic/CapitalFlowLogic.php b/app/common/logic/CapitalFlowLogic.php
new file mode 100644
index 000000000..cbe68c088
--- /dev/null
+++ b/app/common/logic/CapitalFlowLogic.php
@@ -0,0 +1,154 @@
+<?php
+
+namespace app\common\logic;
+
+use app\common\model\finance\CapitalFlow;
+
+class CapitalFlowLogic extends BaseLogic
+{
+
+    public $user;
+
+    public function __construct($user)
+    {
+        $this->user = $user;
+    }
+
+    /**
+     * 用户收入
+     * @param $category
+     * @param $linkType
+     * @param $linkId
+     * @param $amount
+     * @param $mark
+     * @return mixed
+     */
+    public function userIncome($category, $linkType, $linkId, $amount, $mark = '')
+    {
+        $model = new CapitalFlow();
+        $model->uid = $this->user['uid'];
+        $model->category = $category;
+        $model->link_type = $linkType;
+        $model->link_id = $linkId;
+        $model->amount = $amount;
+        $model->before_balance = $this->user['now_money'];
+        $model->balance = bcadd($this->user['now_money'], $amount, 2);
+        $model->create_time = date('Y-m-d H:i:s');
+        $model->type = 'in';
+        $model->title = $this->getTitle($category, $amount);
+        $model->mark = empty($mark) ? $model->title : $mark;
+        $model->save();
+        return $model->id;
+    }
+
+    /**
+     * 用户支出
+     * @param $category
+     * @param $linkType
+     * @param $linkId
+     * @param $amount
+     * @param $mark
+     * @return mixed
+     */
+    public function userExpense($category, $linkType, $linkId, $amount, $mark = '')
+    {
+        $model = new CapitalFlow();
+        $model->uid = $this->user['uid'];
+        $model->category = $category;
+        $model->link_type = $linkType;
+        $model->link_id = $linkId;
+        $model->amount = $amount;
+        $model->before_balance = $this->user['now_money'];
+        $model->balance = bcsub($this->user['now_money'], $amount, 2);
+        $model->create_time = date('Y-m-d H:i:s');
+        $model->type = 'out';
+        $model->title = $this->getTitle($category, $amount);
+        $model->mark = empty($mark) ? $model->title : $mark;
+        $model->save();
+        return $model->id;
+    }
+
+    /**
+     * 商户收入
+     * @param $category
+     * @param $linkType
+     * @param $linkId
+     * @param $amount
+     * @param $mark
+     * @return mixed
+     */
+    public function merchantIncome($category, $linkType, $linkId, $amount, $mark = '')
+    {
+        $model = new CapitalFlow();
+        $model->mer_id = $this->user['mer_id'];
+        $model->category = $category;
+        $model->link_type = $linkType;
+        $model->link_id = $linkId;
+        $model->amount = $amount;
+        $model->before_balance = $this->user['mer_money'];
+        $model->balance = bcadd($this->user['mer_money'], $amount, 2);
+        $model->create_time = date('Y-m-d H:i:s');
+        $model->type = 'in';
+        $model->title = $this->getTitle($category, $amount);
+        $model->mark = empty($mark) ? $model->title : $mark;
+        $model->save();
+        return $model->id;
+    }
+
+    /**
+     * 商户支出
+     * @param $category
+     * @param $linkType
+     * @param $linkId
+     * @param $amount
+     * @param $mark
+     * @return mixed
+     */
+    public function merchantExpense($category, $linkType, $linkId, $amount, $mark = '')
+    {
+        $model = new CapitalFlow();
+        $model->mer_id = $this->user['mer_id'];
+        $model->uid = $this->user['uid'];
+        $model->category = $category;
+        $model->link_type = $linkType;
+        $model->link_id = $linkId;
+        $model->amount = $amount;
+        $model->before_balance = $this->user['mer_money'];
+        $model->balance = bcsub($this->user['mer_money'], $amount, 2);
+        $model->create_time = date('Y-m-d H:i:s');
+        $model->type = 'out';
+        $model->title = $this->getTitle($category, $amount);
+        $model->mark = empty($mark) ? $model->title : $mark;
+        $model->save();
+        return $model->id;
+    }
+
+    public function getTitle($category, $amount)
+    {
+        switch ($category) {
+            case 'user_balance_recharge':
+                return "用户充值{$amount}元";
+            case 'merchant_margin':
+                return "店铺自动扣除保证金{$amount}元";
+            case 'merchant_order_income':
+                return "店铺订单收入{$amount}元";
+            case 'user_order_refund':
+                return "用户订单退款{$amount}元";
+            case 'merchant_order_refund':
+                return "店铺订单退款{$amount}元";
+            case 'merchant_margin_refund':
+                return "店铺退还保证金{$amount}元";
+            case 'user_order_promotion':
+                return "订单推广佣金{$amount}元";
+            case 'user_order_promotion_refund':
+                return "退还订单推广佣金{$amount}元";
+            case 'system_balance_add':
+                return "系统增加余额{$amount}元";
+            case 'system_balance_reduce':
+                return "系统减少余额{$amount}元";
+            default:
+                return "订单支付{$amount}元";
+        }
+    }
+
+}
diff --git a/app/common/logic/PayNotifyLogLogic.php b/app/common/logic/PayNotifyLogLogic.php
new file mode 100644
index 000000000..99c2aa792
--- /dev/null
+++ b/app/common/logic/PayNotifyLogLogic.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace app\common\logic;
+
+use app\common\model\finance\PayNotifyLog;
+use support\Log;
+
+class PayNotifyLogLogic extends BaseLogic
+{
+
+    public function insert($payType, $data, $type = PayNotifyLog::TYPE_ORDER)
+    {
+        try {
+            $exist = PayNotifyLog::where('order_sn', $data['out_trade_no'])->where('pay_type', $payType)->where('type', $type)->count();
+            if ($exist) {
+                return false;
+            }
+            $model = new PayNotifyLog();
+            $model->pay_type = $payType;
+            $model->order_sn = $data['out_trade_no'];
+            $model->type = $type;
+            $model->amount = $payType == 'wechat_common' ? $data['amount']['payer_total'] : $data['buyer_pay_amount'];
+            $model->out_trade_no = $payType == 'wechat_common' ? $data['transaction_id'] : $data['trade_no'];
+            $model->transaction_id = $data['transaction_id'];
+            $model->attach = $data['attach'] ?? '';
+            if (isset($data['pay_time'])) {
+                $model->create_time = $data['pay_time'];
+            }
+            if (isset($data['success_time'])) {
+                $model->create_time = $data['success_time'];
+            }
+            $model->create_time = $model->create_time ?: date('Y-m-d H:i:s');
+            $model->save();
+            return $model->id;
+        } catch (\Exception $e) {
+            $message = 'pay notify log insert error: ' . $e->getMessage();
+            Log::error($message . ', trace: ' . $e->getTraceAsString());
+        }
+        return false;
+    }
+
+}
diff --git a/app/common/logic/PayNotifyLogic.php b/app/common/logic/PayNotifyLogic.php
index 66da67568..e73a84df8 100644
--- a/app/common/logic/PayNotifyLogic.php
+++ b/app/common/logic/PayNotifyLogic.php
@@ -23,6 +23,10 @@ class PayNotifyLogic extends BaseLogic
     {
         Db::startTrans();
         try {
+            if ($action != 'cash_pay') {
+                $payNotifyLogLogic = new PayNotifyLogLogic();
+                $payNotifyLogLogic->insert($action, $extra);
+            }
             self::$action($orderSn, $extra);
             Db::commit();
             return true;
@@ -54,53 +58,25 @@ class PayNotifyLogic extends BaseLogic
         if ($order->isEmpty() || $order->paid == PayEnum::ISPAID) {
             return true;
         }
-        $financial_type = OrderEnum::USER_ORDER_PAY;
-        $financial_type2 = OrderEnum::MERCHANT_ORDER_OBTAINS;
         if ($order->pay_type != 10) {
             $order->pay_price = bcdiv($extra['amount']['payer_total'], 100, 2);
             $order->paid = 1;
             $order->status = 1;
             $order->save();
         } else {
-            $financial_type2 = OrderEnum::CASHIER_CASH_ORDER_PAY;
             $extra['transaction_id'] = time();
         }
         if ($order->pay_type == 9) {
             $order->status = 2;
-            $financial_type2 = OrderEnum::CASHIER_ORDER_PAY;
         }
+        $financeLogic = new StoreFinanceFlowLogic();
+        $financeLogic->order = $order;
+        $financeLogic->user = ['uid' => $order['uid']];
         if ($order->pay_type != 9 || $order->pay_type != 10) {
-            //用户支出流水
-            $record[] = [
-                'financial_record_sn' => $extra['transaction_id'],
-                'order_id' => $order['id'],
-                'order_sn' => $order['order_id'],
-                'user_id' => $order['uid'],
-                'financial_type' => $financial_type,
-                'financial_pm' => OrderEnum::EXPENDITURE,
-                'number' => $order['pay_price'],
-                'status' => 1,
-                'type' => OrderEnum::USER,
-                'store_id' => $order['store_id'],
-                'staff_id' => $order['staff_id'],
-            ];
+            $financeLogic->in($order['pay_price'], OrderEnum::USER_ORDER_PAY);
         }
-        //商户获得流水
-        $record[] = [
-            'financial_record_sn' => $extra['transaction_id'],
-            'order_id' => $order['id'],
-            'order_sn' => $order['order_id'],
-            'user_id' => $order['uid'],
-            'financial_type' => $financial_type2,
-            'financial_pm' => OrderEnum::INCOME,
-            'number' => $order['pay_price'],
-            'status' => 0,
-            'type' => OrderEnum::MERCHANT,
-            'store_id' => $order['store_id'],
-            'staff_id' => $order['staff_id'],
-        ];
-        (new StoreFinanceFlow())->saveAll($record);
-
+        $financeLogic->out($order['pay_price'], OrderEnum::MERCHANT_ORDER_OBTAINS, $order['store_id'], $order['staff_id'], 0);
+        $financeLogic->save();
 
         if ($order->pay_type == 9) {
             $extra['create_time'] = $order['create_time'];
@@ -115,7 +91,7 @@ class PayNotifyLogic extends BaseLogic
         }
         return true;
     }
- 
+
     /**
      * 现金支付
      */
@@ -160,50 +136,25 @@ class PayNotifyLogic extends BaseLogic
         if ($order->isEmpty() || $order->paid == PayEnum::ISPAID) {
             return true;
         }
-        $financial_type = OrderEnum::USER_ORDER_PAY;
-        $financial_type2 = OrderEnum::MERCHANT_ORDER_OBTAINS;
         if ($order->pay_type != 10) {
             $order->money = $extra['buyer_pay_amount'];
             $order->paid = 1;
             $order->status = 1;
             $order->save();
         } else {
-            $financial_type2 = OrderEnum::CASHIER_CASH_ORDER_PAY;
             $extra['transaction_id'] = time();
         }
         if ($order->pay_type == 9) {
             $order->status = 2;
-            $financial_type2 = OrderEnum::CASHIER_ORDER_PAY;
         }
+        $financeLogic = new StoreFinanceFlowLogic();
+        $financeLogic->order = $order;
+        $financeLogic->user = ['uid' => $order['uid']];
         if ($order->pay_type != 9 || $order->pay_type != 10) {
-            //用户支出流水
-            $record[] = [
-                'financial_record_sn' => $extra['trade_no'],
-                'order_id' => $order['id'],
-                'order_sn' => $order['order_id'],
-                'user_id' => $order['uid'],
-                'financial_type' => $financial_type,
-                'financial_pm' => OrderEnum::EXPENDITURE,
-                'number' => $order['actual'],
-                'status' => 1,
-                'type' => OrderEnum::USER,
-                'mer_id' => $order['merchant'],
-            ];
+            $financeLogic->in($order['pay_price'], OrderEnum::USER_ORDER_PAY);
         }
-        //商户获得流水
-        $record[] = [
-            'financial_record_sn' => $extra['trade_no'],
-            'order_id' => $order['id'],
-            'order_sn' => $order['order_id'],
-            'user_id' => $order['uid'],
-            'financial_type' => $financial_type2,
-            'financial_pm' => OrderEnum::INCOME,
-            'number' => $order['actual'],
-            'status' => 0,
-            'type' => OrderEnum::MERCHANT,
-            'mer_id' => $order['merchant'],
-        ];
-        (new StoreFinanceFlow())->saveAll($record);
+        $financeLogic->out($order['pay_price'], OrderEnum::MERCHANT_ORDER_OBTAINS, $order['store_id'], $order['staff_id'], 0);
+        $financeLogic->save();
 
 
         if ($order->pay_type == 9) {
diff --git a/app/common/logic/StoreFinanceFlowLogic.php b/app/common/logic/StoreFinanceFlowLogic.php
new file mode 100644
index 000000000..d1682a305
--- /dev/null
+++ b/app/common/logic/StoreFinanceFlowLogic.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace app\common\logic;
+
+use app\common\model\store_finance_flow\StoreFinanceFlow;
+
+class StoreFinanceFlowLogic extends BaseLogic
+{
+
+    public $order;
+    public $user;
+    public $index = 0;
+    public $financeSn;
+    public $list = [];
+
+    /**
+     * 支出财务流水
+     * @param $number
+     * @param $financialType
+     * @param $storeId
+     * @param $staffId
+     * @param $status
+     */
+    public function out($number, $financialType, $storeId = 0, $staffId = 0, $status = 1)
+    {
+        $this->setData($number, $financialType, 0, $storeId, $staffId, $status);
+    }
+
+    /**
+     * 收入财务流水
+     * @param $number
+     * @param $financialType
+     * @param $storeId
+     * @param $staffId
+     * @param $status
+     */
+    public function in($number, $financialType, $storeId = 0, $staffId = 0, $status = 1)
+    {
+        $this->setData($number, $financialType, 1, $storeId, $staffId, $status);
+    }
+
+    public function setData($number, $financialType, $pm, $storeId, $staffId, $status)
+    {
+        if (empty($this->financeSn)) {
+            $this->financeSn = $this->getSn();
+        }
+        $this->list[] = [
+            'order_id' => $this->order['id'],
+            'order_sn' => $this->order['order_id'],
+            'user_id' => $this->user['uid'],
+            'financial_type' => $financialType,
+            'financial_pm' => $pm,
+            'number' => $number,
+            'status' => $status,
+            'store_id' => $storeId !== '' ? $storeId : $this->order['store_id'],
+            'staff_id' => $staffId !== '' ? $staffId : $this->order['staff_id'],
+            'financial_record_sn' => $this->financeSn . ($this->index++)
+        ];
+    }
+
+    public function save()
+    {
+        if (count($this->list) > 0) {
+            (new StoreFinanceFlow())->insertAll($this->list);
+        }
+    }
+
+    public function getSn()
+    {
+        list($msec, $sec) = explode(' ', microtime());
+        $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
+        return 'fn' . $msectime . mt_rand(10000, max(intval($msec * 10000) + 10000, 98369));
+    }
+
+}
diff --git a/app/common/model/finance/CapitalFlow.php b/app/common/model/finance/CapitalFlow.php
new file mode 100644
index 000000000..08d68441c
--- /dev/null
+++ b/app/common/model/finance/CapitalFlow.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace app\common\model\finance;
+
+use app\common\model\BaseModel;
+
+class CapitalFlow extends BaseModel
+{
+
+}
diff --git a/app/common/model/finance/PayNotifyLog.php b/app/common/model/finance/PayNotifyLog.php
new file mode 100644
index 000000000..60ef81506
--- /dev/null
+++ b/app/common/model/finance/PayNotifyLog.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace app\common\model\finance;
+
+use app\common\model\BaseModel;
+
+class PayNotifyLog extends BaseModel
+{
+
+    const TYPE_ORDER = 1;
+    const TYPE_REFUND = 2;
+
+}
diff --git a/app/store/controller/store_order/StoreOrderController.php b/app/store/controller/store_order/StoreOrderController.php
index c69042aef..85f73d30c 100644
--- a/app/store/controller/store_order/StoreOrderController.php
+++ b/app/store/controller/store_order/StoreOrderController.php
@@ -3,8 +3,8 @@
 namespace app\store\controller\store_order;
 
 
+use app\admin\lists\store_order\StoreOrderLists;
 use app\store\controller\BaseAdminController;
-use app\store\lists\store_order\StoreOrderLists;
 use app\store\logic\store_order\StoreOrderLogic;
 use app\store\validate\store_order\StoreOrderValidate;
 use hg\apidoc\annotation as ApiDoc;