<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## crmeb [TOC=3,8] ---- ### 訂單 與 支付 #### 訂單表 ```sql CREATE TABLE IF NOT EXISTS `eb_store_order` ( `paid` tinyint(1) NOT NULL DEFAULT '0' COMMENT '支付狀態 0: 未支付 1:已支付', `pay_time` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '支付時間', `pay_type` varchar(32) NOT NULL DEFAULT '' COMMENT '支付方式', `add_time` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '創建時間', `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '訂單狀態(-1 : 申請退款 -2 : 退貨成功 0:待發貨;1:待收貨;2:已收貨;3:待評價;-1:已退款)', `refund_status` tinyint(1) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0 未退款 1 申請中 2 已退款', `refund_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '退款申請類型', `refund_express` varchar(255) NOT NULL DEFAULT '' COMMENT '退貨快遞單號', `refund_express_name` varchar(255) NOT NULL DEFAULT '' COMMENT '退貨快遞名稱', `refund_reason_wap_img` varchar(2000) NOT NULL DEFAULT '' COMMENT '退款圖片', `refund_reason_wap_explain` varchar(255) NOT NULL DEFAULT '' COMMENT '退款用戶說明', `refund_reason_time` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '退款時間', `refund_reason_wap` varchar(255) NOT NULL DEFAULT '' COMMENT '前臺退款原因', `refund_reason` varchar(255) NOT NULL DEFAULT '' COMMENT '不退款的理由', `refund_price` decimal(8,2) UNSIGNED NOT NULL DEFAULT '0.00' COMMENT '退款金額', PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='訂單表'; ``` #### 分析 支付回執 AliPayService.php ```php public static function handleNotify() { return self::instance()->notify(function ($notify) { if (isset($notify->out_trade_no)) { if (isset($notify->attach) && $notify->attach) { if (($count = strpos($notify->out_trade_no, '_')) !== false) { $notify->trade_no = $notify->out_trade_no; $notify->out_trade_no = substr($notify->out_trade_no, $count + 1); } return (new Hook(PayNotifyServices::class, 'aliyun'))->listen($notify->attach, $notify->out_trade_no, $notify->trade_no); } return false; } }); } public function notify(callable $notifyFn) { app()->request->filter(['trim']); //商戶訂單號 $postOrder['out_trade_no'] = $paramInfo['out_trade_no'] ?? ''; //支付寶交易號 $postOrder['trade_no'] = $paramInfo['trade_no'] ?? ''; //交易狀態 $postOrder['trade_status'] = $paramInfo['trade_status'] ?? ''; //備注 $postOrder['attach'] = isset($paramInfo['passback_params']) ? urldecode($paramInfo['passback_params']) : ''; if (in_array($paramInfo['trade_status'], ['TRADE_SUCCESS', 'TRADE_FINISHED']) && $this->verifyNotify($paramInfo)) { try { if ($notifyFn((object)$postOrder)) { return 'success'; } } catch (\Exception $e) { Log::error('支付寶異步會回調成功,執行函數錯誤。錯誤單號:' . $postOrder['out_trade_no']); } } return 'fail'; } ``` 業務回執處理 PayNotifyServices.php ```php public function aliyunProduct(string $order_id = null, string $trade_no = null) { if (!$order_id || !$trade_no) { return false; } try { /** @var StoreOrderSuccessServices $services */ $services = app()->make(StoreOrderSuccessServices::class); $orderInfo = $services->getOne(['order_id' => $order_id]); if (!$orderInfo) return true; if ($orderInfo->paid) return true; return $services->paySuccess($orderInfo->toArray(), PayServices::ALIAPY_PAY, ['trade_no' => $trade_no]); } catch (\Throwable $e) { return false; } } ``` StoreOrderSuccessServices.php ```php public function paySuccess(array $orderInfo, string $paytype = PayServices::WEIXIN_PAY, array $other = []) { $updata = ['paid' => 1, 'pay_type' => $paytype, 'pay_time' => time()]; if ($other && isset($other['trade_no'])) { $updata['trade_no'] = $other['trade_no']; } $res1 = $this->dao->update($orderInfo['id'], $updata); $resPink = true; if ($orderInfo['combination_id'] && $res1 && !$orderInfo['refund_status']) { /** @var StorePinkServices $pinkServices */ $pinkServices = app()->make(StorePinkServices::class); /** @var StoreOrderServices $orderServices */ $orderServices = app()->make(StoreOrderServices::class); $resPink = $pinkServices->createPink($orderServices->tidyOrder($orderInfo, true));//創建拼團 } //緩存抽獎次數 除過線下支付 if (isset($orderInfo['pay_type']) && $orderInfo['pay_type'] != 'offline') { /** @var LuckLotteryServices $luckLotteryServices */ $luckLotteryServices = app()->make(LuckLotteryServices::class); $luckLotteryServices->setCacheLotteryNum((int)$orderInfo['uid'], 'order'); } //訂單支付成功后置事件 event('order.orderPaySuccess', [$orderInfo]); //用戶推送消息事件 event('notice.notice', [$orderInfo, 'order_pay_success']); //支付成功給客服發送消息 event('notice.notice', [$orderInfo, 'admin_pay_success_code']); $res = $res1 && $resPink; return false !== $res; } ``` #### 總結 1. 只在 PayNotifyServices 成功 才對 三方 響應 'success' 2. PayNotifyServices 成功 a. 訂單不存在 true b. 訂單已支付 true c. StoreOrderSuccessServices->paySuccess() true a. 更新訂單支付狀態 成功 b. 訂單支付成功后置事件 結果不關心 1. 只在 PayNotifyServices 成功 才對 三方 響應 'success' 2. PayNotifyServices 成功 a. 訂單不存在 true b. 訂單已支付 true c. wechatUserRecharge->rechargeSuccess() true a. 更新訂單 true b. 更新用戶余額 b. 訂單支付成功后置事件 結果不關心 不過任何 異常 代碼錯誤,都會使 PayNotifyServices false ,所以如果 代碼問題,業務履行失敗 都不會 對三方響應 'success' ---- ### 架構 Dao 基于模型對數據獲取、操作進行封裝,Services 使用 Dao 進行數據操作。調用 Services 上不存在的方法 會調用 到 其 Dao 上,所以 Services 可看作 是 “繼承” Dao 的。 優點:將 SQL 拼裝 從 業務層拆分到 Dao 上了,Services 層的業務成分就更明顯了。 缺點:由于優點,于是 業務也被分散到 Services 和 Dao 上了,有點不清晰,只能說 Dao 的 業務成分 沒有 Services 明顯,但并不是完全沒有。 結論: 1. 所以 Services + Dao = 我們 的 Logic 2. Services > Dao > Model ;我們 Logic > Model PS: ~~我們的 Logic、Service 層確實沒什么區別,區分的理由實在太過牽強,沒有區分的意義。~~(有待商榷,Logic 注重特定的業務場景 如 User,Service 純技術方案,無特定業務場景特征,如 JWT) ---- ```php abstract class BaseServices { public function __call($name, $arguments) { // TODO: Implement __call() method. return call_user_func_array([$this->dao, $name], $arguments); } } class StoreOrderServices extends BaseServices { public function setOrderTypePayOffline(string $orderId) { return $this->dao->update($orderId, ['pay_type' => 'offline'], 'order_id'); } public function removeOrder(string $uni, int $uid) { $order = $this->getUserOrderDetail($uni, $uid); if (!$order) { throw new ValidateException('訂單不存在!'); } ... } } ``` ```php abstract class BaseDao { abstract protected function setModel(): string; protected function getModel() { return app()->make($this->setModel()); } protected function getPk() { return $this->getModel()->getPk(); } public function update($id, array $data, ?string $key = null) { if (is_array($id)) { $where = $id; } else { $where = [is_null($key) ? $this->getPk() : $key => $id]; } return $this->getModel()::update($data, $where); } } class StoreOrderDao extends BaseDao { protected function setModel(): string { return StoreOrder::class; } public function getUserOrderDetail(string $key, int $uid, $with = []) { return $this->getOne(['order_id|unique' => $key, 'uid' => $uid, 'is_del' => 0], '*', $with); } public function batchUpdateOrder(array $ids, array $data, ?string $key = null) { return $this->getModel()::whereIn(is_null($key) ? $this->getPk() : $key, $ids)->update($data); } } ``` ---- [分層 DAO層,Service層,Controller層、View層 - 簡書](https://www.jianshu.com/p/df659d7fbbf7) > DAO完成連接數據庫修改刪除添加等的實現細節,例如sql語句是怎么寫的,怎么把對象放入數據庫的。service層是面向功能的,一個個功能模塊比如說銀行登記并完成一次存款,UI要把請求給service層,然后service曾將這一個case分解成許多步驟調用底層的實現完成這次存款,dao就是下面那層。 [淺談MyBatis-Plus學習之ActiveRecord - hjjay - 博客園](https://www.cnblogs.com/jayhou/p/9824232.html) > Active Record(簡稱AR),是一種領域模型模式,特點是一個模型類對應關系型數據庫中的一個表,而模型類的一個實例對應表中的一行記錄。 [極簡架構模式-數據訪問對象模式 | Laravel China 社區](https://learnku.com/articles/63753) [dao層寫法有什么好處? | Laravel | Laravel China 社區](https://learnku.com/laravel/t/60443)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看