From 1161f06aeb120313b0ed1e7471eb05ad9357c639 Mon Sep 17 00:00:00 2001 From: cano Date: Mon, 11 Mar 2024 02:21:52 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E3=80=81=E7=BA=A0=E7=BA=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomerUserPostOrderDisputeBean.php | 277 ++++++++++++++++++ .../CustomerWalletBalanceTransactionBean.php | 11 + ....php => DailyCheckUserActiveStatusCmd.php} | 4 +- .../HourCustomerWalletTrsDelayPayCmd.php | 35 +++ app/Console/Kernel.php | 3 +- app/Const/Prefix.php | 8 + .../CustomerUserPostOrderDisputeModel.php | 248 ++++++++++++++++ .../Api/Order/CustomerUserPostOrderModel.php | 67 ++++- app/Models/Api/Post/PostHistoryModel.php | 10 + .../CustomerPostOrderWalletCheckbookModel.php | 27 -- .../CustomerWalletBalanceTransactionModel.php | 134 ++++++++- app/Tools/Logs.php | 4 +- app/Tools/Tools.php | 7 + composer.json | 5 +- composer.lock | 68 ++++- 15 files changed, 855 insertions(+), 53 deletions(-) create mode 100644 app/Bean/Model/Api/Order/CustomerUserPostOrderDisputeBean.php rename app/Console/Commands/{DailyCheckUserActiveStatus.php => DailyCheckUserActiveStatusCmd.php} (85%) create mode 100644 app/Console/Commands/HourCustomerWalletTrsDelayPayCmd.php create mode 100644 app/Const/Prefix.php delete mode 100644 app/Models/Api/Wallet/CustomerPostOrderWalletCheckbookModel.php diff --git a/app/Bean/Model/Api/Order/CustomerUserPostOrderDisputeBean.php b/app/Bean/Model/Api/Order/CustomerUserPostOrderDisputeBean.php new file mode 100644 index 0000000..b42d6b2 --- /dev/null +++ b/app/Bean/Model/Api/Order/CustomerUserPostOrderDisputeBean.php @@ -0,0 +1,277 @@ +buyer_uid; + } + + public function setBuyerUid($buyer_uid): void + { + $this->buyer_uid = $buyer_uid; + } + + public function getSellerUid() + { + return $this->seller_uid; + } + + public function setSellerUid($seller_uid): void + { + $this->seller_uid = $seller_uid; + } + + public function getBuyerDisputeFeePayStatus() + { + return $this->buyer_dispute_fee_pay_status; + } + + public function setBuyerDisputeFeePayStatus($buyer_dispute_fee_pay_status): void + { + $this->buyer_dispute_fee_pay_status = $buyer_dispute_fee_pay_status; + } + + + public function getId() + { + return $this->id; + } + + public function setId($id): void + { + $this->id = $id; + } + + public function getPostOrderId() + { + return $this->post_order_id; + } + + public function setPostOrderId($post_order_id): void + { + $this->post_order_id = $post_order_id; + } + + public function getStatus() + { + return $this->status; + } + + public function setStatus($status): void + { + $this->status = $status; + } + + public function getChatGroupId() + { + return $this->chat_group_id; + } + + public function setChatGroupId($chat_group_id): void + { + $this->chat_group_id = $chat_group_id; + } + + public function getSellerSubmitDatetime() + { + return $this->seller_submit_datetime; + } + + public function setSellerSubmitDatetime($seller_submit_datetime): void + { + $this->seller_submit_datetime = $seller_submit_datetime; + } + + public function getBuyerSubmitDatetime() + { + return $this->buyer_submit_datetime; + } + + public function setBuyerSubmitDatetime($buyer_submit_datetime): void + { + $this->buyer_submit_datetime = $buyer_submit_datetime; + } + + public function getResultStatus() + { + return $this->result_status; + } + + public function setResultStatus($result_status): void + { + $this->result_status = $result_status; + } + + public function getBuyerPayDisputeStatus() + { + return $this->buyer_pay_dispute_status; + } + + public function setBuyerPayDisputeStatus($buyer_pay_dispute_status): void + { + $this->buyer_pay_dispute_status = $buyer_pay_dispute_status; + } + + public function getBuyerPayAmount() + { + return $this->buyer_pay_amount; + } + + public function setBuyerPayAmount($buyer_pay_amount): void + { + $this->buyer_pay_amount = $buyer_pay_amount; + } + + public function getBuyerPayTransactionId() + { + return $this->buyer_pay_transaction_id; + } + + public function setBuyerPayTransactionId($buyer_pay_transaction_id): void + { + $this->buyer_pay_transaction_id = $buyer_pay_transaction_id; + } + + public function getBuyerDisputeFeeAmount() + { + return $this->buyer_dispute_fee_amount; + } + + public function setBuyerDisputeFeeAmount($buyer_dispute_fee_amount): void + { + $this->buyer_dispute_fee_amount = $buyer_dispute_fee_amount; + } + + public function getBuyerDisputeFeePayTransactionId() + { + return $this->buyer_dispute_fee_pay_transaction_id; + } + + public function setBuyerDisputeFeePayTransactionId($buyer_dispute_fee_pay_transaction_id): void + { + $this->buyer_dispute_fee_pay_transaction_id = $buyer_dispute_fee_pay_transaction_id; + } + + public function getSellerPayDisputeStatus() + { + return $this->seller_pay_dispute_status; + } + + public function setSellerPayDisputeStatus($seller_pay_dispute_status): void + { + $this->seller_pay_dispute_status = $seller_pay_dispute_status; + } + + public function getSellerPayAmount() + { + return $this->seller_pay_amount; + } + + public function setSellerPayAmount($seller_pay_amount): void + { + $this->seller_pay_amount = $seller_pay_amount; + } + + public function getSellerPayTransactionId() + { + return $this->seller_pay_transaction_id; + } + + public function setSellerPayTransactionId($seller_pay_transaction_id): void + { + $this->seller_pay_transaction_id = $seller_pay_transaction_id; + } + + public function getSellerDescKey() + { + return $this->seller_desc_key; + } + + public function setSellerDescKey($seller_desc_key): void + { + $this->seller_desc_key = $seller_desc_key; + } + + public function getSellerDesc() + { + return $this->seller_desc; + } + + public function setSellerDesc($seller_desc): void + { + $this->seller_desc = $seller_desc; + } + + public function getAdminRemark() + { + return $this->admin_remark; + } + + public function setAdminRemark($admin_remark): void + { + $this->admin_remark = $admin_remark; + } + + public function getAdminUid() + { + return $this->admin_uid; + } + + public function setAdminUid($admin_uid): void + { + $this->admin_uid = $admin_uid; + } + + public function getCreatedAt() + { + return $this->created_at; + } + + public function setCreatedAt($created_at): void + { + $this->created_at = $created_at; + } + + public function getUpdatedAt() + { + return $this->updated_at; + } + + public function setUpdatedAt($updated_at): void + { + $this->updated_at = $updated_at; + } + + + + +} diff --git a/app/Bean/Model/Api/Wallet/CustomerWalletBalanceTransactionBean.php b/app/Bean/Model/Api/Wallet/CustomerWalletBalanceTransactionBean.php index 25221fa..0a4e2c1 100644 --- a/app/Bean/Model/Api/Wallet/CustomerWalletBalanceTransactionBean.php +++ b/app/Bean/Model/Api/Wallet/CustomerWalletBalanceTransactionBean.php @@ -20,12 +20,23 @@ class CustomerWalletBalanceTransactionBean extends BaseBean protected $remark; protected $target_uid; protected $target_post_order_id; + protected $target_post_order_dispute_id; protected $sign; protected $callback_time; protected $delay_payment_time; protected $created_at; protected $updated_at; + public function getTargetPostOrderDisputeId() + { + return $this->target_post_order_dispute_id; + } + + public function setTargetPostOrderDisputeId($target_post_order_dispute_id): void + { + $this->target_post_order_dispute_id = $target_post_order_dispute_id; + } + public function getId() { return $this->id; diff --git a/app/Console/Commands/DailyCheckUserActiveStatus.php b/app/Console/Commands/DailyCheckUserActiveStatusCmd.php similarity index 85% rename from app/Console/Commands/DailyCheckUserActiveStatus.php rename to app/Console/Commands/DailyCheckUserActiveStatusCmd.php index 5436ada..6a5f691 100644 --- a/app/Console/Commands/DailyCheckUserActiveStatus.php +++ b/app/Console/Commands/DailyCheckUserActiveStatusCmd.php @@ -5,14 +5,14 @@ namespace App\Console\Commands; use App\Models\Api\Customer\CustomerUserExtendModel; use Illuminate\Console\Command; -class DailyCheckUserActiveStatus extends Command +class DailyCheckUserActiveStatusCmd extends Command { /** * The name and signature of the console command. * * @var string */ - protected $signature = 'app:daily-check-user-active-status'; + protected $signature = 'app:daily-check-user-active-status-cmd'; /** * The console command description. diff --git a/app/Console/Commands/HourCustomerWalletTrsDelayPayCmd.php b/app/Console/Commands/HourCustomerWalletTrsDelayPayCmd.php new file mode 100644 index 0000000..6d88077 --- /dev/null +++ b/app/Console/Commands/HourCustomerWalletTrsDelayPayCmd.php @@ -0,0 +1,35 @@ +info('每小时检查用户钱包交易延迟支付'); + $this->info('开始...'); + $oCustomerWalletBalanceTransactionModel = new CustomerWalletBalanceTransactionModel(); + $oCustomerWalletBalanceTransactionModel->dealDelayPaymentTransactionCmd(); + $this->info('结束...'); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 1c275dd..f304417 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -13,7 +13,8 @@ class Kernel extends ConsoleKernel protected function schedule(Schedule $schedule): void { // $schedule->command('inspire')->hourly(); - $schedule->command('app:daily-check-user-active-status')->dailyAt('00:30')->onOneServer(); + $schedule->command('app:daily-check-user-active-status-cmd')->dailyAt('00:30')->onOneServer(); + $schedule->command('app:hour-customer-wallet-trs-delay-pay-cmd')->hourly()->onOneServer(); } /** diff --git a/app/Const/Prefix.php b/app/Const/Prefix.php new file mode 100644 index 0000000..0ea779c --- /dev/null +++ b/app/Const/Prefix.php @@ -0,0 +1,8 @@ + '无纠纷', + self::STATUS_WAITING => '待处理', + self::STATUS_PROCESSING => '处理中', + self::STATUS_FINISH => '处理完成', + self::STATUS_CANCEL => '取消', + ]; + + const RESULT_STATUS_SELLER_RESPLITY = 1; + const RESULT_STATUS_BUYER_RESPLITY = 2; + const RESULT_STATUS_EACH_RESPLITY = 3; + const RESULT_STATUS_OVERRULE = 4; + const RESULT_STATUS = [ + self::RESULT_STATUS_SELLER_RESPLITY => '卖家责任', + self::RESULT_STATUS_BUYER_RESPLITY => '买家责任', + self::RESULT_STATUS_EACH_RESPLITY => '双方责任', + self::RESULT_STATUS_OVERRULE => '驳回', + ]; + + + const PAY_DISPUTE_STATUS_WAITING = 1; + const PAY_DISPUTE_STATUS_SUCCESS = 2; + const PAY_DISPUTE_STATUS_FAIL = 3; + const PAY_DISPUTE_STATUS = [ + self::PAY_DISPUTE_STATUS_WAITING => '待处理', + self::PAY_DISPUTE_STATUS_SUCCESS => '成功', + self::PAY_DISPUTE_STATUS_FAIL => '失败', + ]; + + const BUYER_DISPUTE_FEE_PAY_STATUS_NO = 1; + const BUYER_DISPUTE_FEE_PAY_STATUS_YES = 2; + const BUYER_DISPUTE_FEE_PAY_STATUS = [ + self::BUYER_DISPUTE_FEE_PAY_STATUS_NO => '未支付', + self::BUYER_DISPUTE_FEE_PAY_STATUS_YES => '已支付', + ]; + + //纠纷管理员接单 + public function disputeAdminAccept($dispute_id, $admin_uid, $is_change_admin = false): bool|int + { + try { + $datetimeNow = Times::getNowDateTime(); + DB::beginTransaction(); + $resModel = $this->findItem($dispute_id); + if (!$resModel) throw new ModelException('dispute not found'); + if ($resModel->status != self::STATUS_WAITING) throw new ModelException('dispute status error'); + if (!empty($resModel->admin_uid) && !$is_change_admin) throw new ModelException('already have admin'); + + $updateItem = [ + 'id' => $resModel->id, + 'status' => self::STATUS_PROCESSING, + 'admin_uid' => $admin_uid, + 'updated_at' => $datetimeNow, + ]; + $res = $this->updateItem($updateItem); + if (!$res) throw new ModelException('update dispute status fail'); + DB::commit(); + Logs::SuccLog(__FUNCTION__, func_get_args()); + return true; + } catch (\Exception $e) { + DB::rollBack(); + Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); + return false; + } + } + + //创建纠纷 + public function createDispute($post_order_id) + { + try { + $datetimeNow = Times::getNowDateTime(); + DB::beginTransaction(); + $oCustomerUserPostOrderModel = new CustomerUserPostOrderModel(); + $resCustomerUserPostOrderModel = $oCustomerUserPostOrderModel->findItem($post_order_id); + if (!$resCustomerUserPostOrderModel) throw new \Exception('order not found'); + if ($resCustomerUserPostOrderModel->pay_status != CustomerUserPostOrderModel::PAY_STATUS_PAID) throw new ModelException('order already in dispute'); + if ($resCustomerUserPostOrderModel->dispute_status != CustomerUserPostOrderModel::DISPUTE_STATUS_UN_DISPUTE) throw new ModelException('order already in dispute'); + //更新订单纠纷状态 + $updateItem = [ + 'id' => $resCustomerUserPostOrderModel->id, + 'dispute_status' => CustomerUserPostOrderModel::DISPUTE_STATUS_WAITING, + 'updated_at' => $datetimeNow, + ]; + $res = $oCustomerUserPostOrderModel->updateItem($updateItem); + if (!$res) throw new ModelException('update order dispute status fail'); + //创建纠纷 + $bean = new CustomerUserPostOrderDisputeBean(); + $bean->setBuyerUid($resCustomerUserPostOrderModel->buyer_uid); + $bean->setSellerUid($resCustomerUserPostOrderModel->seller_uid); + $bean->setPostOrderId($post_order_id); + $bean->setStatus(self::STATUS_WAITING); + $bean->setBuyerDisputeFeePayStatus(self::BUYER_DISPUTE_FEE_PAY_STATUS_NO); + //@@计算纠纷申诉费用 + $bean->setBuyerDisputeFeeAmount(5); //默认5u + $bean->setCreatedAt($datetimeNow); + $bean->setUpdatedAt($datetimeNow); + $resModel = $this->addItem($bean->toArrayNotNull()); + if (!$resModel) throw new ModelException('create dispute fail'); + + //创建聊天群组 + $chat_id = $this->createChatGroupForDispute($resModel->id); + if (!$chat_id) throw new ModelException('create chat group fail'); + $updateItem = [ + 'id' => $resModel->id, + 'chat_group_id' => $chat_id, + ]; + $res = $this->updateItem($updateItem); + if (!$res) throw new ModelException('update chat group id fail'); + + DB::commit(); + Logs::SuccLog(__FUNCTION__, func_get_args()); + return $resModel->id; + } catch (\Exception $e) { + DB::rollBack(); + Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); + return false; + } + } + + //@@创建聊天群组用于纠纷 + function createChatGroupForDispute($dispute_id) + { + return 1; + } + + + //纠纷判罚 + public function disputePenalty($dispute_id, $result_status, $buyer_amount, $seller_amount, $admin_uid, $admin_remark): bool|int + { + try { + if ( + !in_array( + $result_status, + [self::RESULT_STATUS_SELLER_RESPLITY, self::RESULT_STATUS_BUYER_RESPLITY, self::RESULT_STATUS_EACH_RESPLITY, self::RESULT_STATUS_OVERRULE] + ) + ) throw new ModelException('result_status error'); + $datetimeNow = Times::getNowDateTime(); + DB::beginTransaction(); + $resModel = $this->findItem($dispute_id); + if (!$resModel) throw new ModelException('dispute not found'); + if ($resModel->status != self::STATUS_PROCESSING) throw new ModelException('dispute status error'); + if ($resModel->admin_uid != $admin_uid) throw new ModelException('admin_uid error'); + $oCustomerUserPostOrderModel = new CustomerUserPostOrderModel(); + $resCustomerUserPostOrderModel = $oCustomerUserPostOrderModel->findItem($resModel->post_order_id); + if (!$resCustomerUserPostOrderModel) throw new ModelException('order not found'); + if ($resCustomerUserPostOrderModel->dispute_status != CustomerUserPostOrderModel::DISPUTE_STATUS_PROCESSING) throw new ModelException('order dispute status error'); + //更新订单状态 + $updateItem = [ + 'id' => $resCustomerUserPostOrderModel->id, + 'dispute_status' => CustomerUserPostOrderModel::DISPUTE_STATUS_FINISH, + 'dispute_result_status' => $result_status, + 'updated_at' => $datetimeNow, + ]; + $res = $oCustomerUserPostOrderModel->updateItem($updateItem); + if (!$res) throw new ModelException('update order dispute status fail'); + + //执行金额处理 + $oCustomerWalletBalanceTransactionModel = new CustomerWalletBalanceTransactionModel(); + $buyer_pay_status = self::PAY_DISPUTE_STATUS_SUCCESS; + $seller_pay_status = self::PAY_DISPUTE_STATUS_SUCCESS; + //执行买家 + $resBuyerTrsId = $this->changeUserAmountDispute( + $resCustomerUserPostOrderModel->buyer_uid, + $resCustomerUserPostOrderModel->buyer_currency_code, + $buyer_amount, + $resModel->id, + ); + if (!$resBuyerTrsId) { + $buyer_pay_status = self::PAY_DISPUTE_STATUS_FAIL; + $this->changeUserAmountNotEnough($resCustomerUserPostOrderModel->buyer_uid, $resCustomerUserPostOrderModel->buyer_currency_code, $buyer_amount); + } + //执行卖家 + $resSellerTrsId = $this->changeUserAmountDispute( + $resCustomerUserPostOrderModel->seller_uid, + $resCustomerUserPostOrderModel->seller_currency_code, + $seller_amount, + $resModel->id, + ); + if (!$resSellerTrsId) { + $seller_pay_status = self::PAY_DISPUTE_STATUS_FAIL; + $this->changeUserAmountNotEnough($resCustomerUserPostOrderModel->seller_uid, $resCustomerUserPostOrderModel->seller_currency_code, $seller_amount); + } + + //更新纠纷 + $updateItem = [ + 'status' => self::STATUS_FINISH, + 'result_status' => $result_status, + 'admin_remark' => $admin_remark, + 'updated_at' => $datetimeNow, + 'buyer_pay_amount' => $buyer_amount, + 'buyer_pay_dispute_status' => $buyer_pay_status, + 'seller_pay_amount' => $seller_amount, + 'seller_pay_dispute_status' => $seller_pay_status, + ]; + if ($buyer_pay_status == self::PAY_DISPUTE_STATUS_SUCCESS) $updateItem['buyer_pay_transaction_id'] = $resBuyerTrsId; + if ($seller_pay_status == self::PAY_DISPUTE_STATUS_SUCCESS) $updateItem['seller_pay_transaction_id'] = $resSellerTrsId; + $res = $this->updateItem($updateItem); + if (!$res) throw new ModelException('update dispute status fail'); + + DB::commit(); + Logs::SuccLog(__FUNCTION__, func_get_args()); + return true; + } catch (\Exception $e) { + DB::rollBack(); + Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); + return false; + } + } + + //@@金额不足处理 + function changeUserAmountNotEnough($uid, $currency_code, $amount, $remark = '') + { + //@@冻结用户提款功能 + //@@提交到定期扣款任务 + } + + + //纠纷金额处理 + function changeUserAmountDispute($uid, $currency_code, $amount, $dispute_id, $remark = ''): bool|int + { + if ($amount == 0) return true; + $oCustomerWalletBalanceTransactionModel = new CustomerWalletBalanceTransactionModel(); + if ($amount > 0) { + $res = $oCustomerWalletBalanceTransactionModel->typeDisputeAdd($uid, $currency_code, $amount, $dispute_id, $remark); + } else { + $res = $oCustomerWalletBalanceTransactionModel->typeDisputeSub($uid, $currency_code, $amount, $dispute_id, $remark); + } + return $res; + } + + } diff --git a/app/Models/Api/Order/CustomerUserPostOrderModel.php b/app/Models/Api/Order/CustomerUserPostOrderModel.php index a097b44..c5bd0cb 100644 --- a/app/Models/Api/Order/CustomerUserPostOrderModel.php +++ b/app/Models/Api/Order/CustomerUserPostOrderModel.php @@ -1,8 +1,15 @@ '未支付', + self::PAY_STATUS_PAID => '已支付', + self::PAY_STATUS_PAID_FAIL => '支付失败', + self::PAY_STATUS_CANCEL => '取消', + ]; const DISPUTE_STATUS_UN_DISPUTE = 1; const DISPUTE_STATUS_WAITING = 2; @@ -42,12 +55,48 @@ class CustomerUserPostOrderModel extends ApiBaseModel self::DISPUTE_STATUS_FINISH => '申诉完成', ]; - const DISPUTE_RESULT_STATUS_NO_MISTAKE = 1; - const DISPUTE_RESULT_STATUS_HAVE_MISTAKE = 2; - const DISPUTE_RESULT_STATUS = [ - self::DISPUTE_RESULT_STATUS_NO_MISTAKE => '无过错', - self::DISPUTE_RESULT_STATUS_HAVE_MISTAKE => '有过错', - ]; + //订单购买 + public function buy($buyer_uid, $seller_id,$currency_code, $amount, $post_id): bool|int + { + try { + $sn = Tools::genSnowflakeId(Prefix::ORDER_SN_PREFIX); + $datetimeNow = Times::getNowDateTime(); + $bean = new CustomerUserPostOrderBean(); + $bean->setAmount(abs($amount)); + $bean->setSn($sn); + $bean->setPayStatus(self::PAY_STATUS_UNPAID); + $bean->setBuyerUid($buyer_uid); //买家 + $bean->setSellerUid($seller_id); //卖家 + $bean->setPid($post_id); + $bean->setBuyerCurrencyCode($currency_code); //买家 + $bean->setSellerCurrencyCode($currency_code); //卖家 + $bean->setDisputeStatus(self::DISPUTE_STATUS_UN_DISPUTE); //纠纷状态 + $bean->setCreatedAt($datetimeNow); + $bean->setUpdatedAt($datetimeNow); + + //查找post_history_id做快照 + $oPostHistoryModel = new PostHistoryModel(); + $resPostHistoryModel = $oPostHistoryModel->findLastPostId($post_id,['id']); + if(!$resPostHistoryModel) throw new ModelException('post_history_id not found'); + $bean->setPostHistoryId($resPostHistoryModel->id); + + $res = $this->addItem($bean->toArray()); + if(!$res) throw new ModelException('order add fail'); + $bean->setId($res->id); + + //进行支付 + $oCustomerWalletBalanceTransactionModel = new CustomerWalletBalanceTransactionModel(); + $res = $oCustomerWalletBalanceTransactionModel->typeOrderPay($bean); //订单支付,内部会进行order状态的更新 + if(!$res) throw new ModelException('order pay fail'); + + Logs::SuccLog(__FUNCTION__, func_get_args()); + return $bean->getId(); + }catch (\Exception $e){ + Logs::ErrLog(__FUNCTION__ . ' ' . 'catchErr', $e, func_get_args()); +// throw new ModelException($e->getMessage()); + return false; + } + } } diff --git a/app/Models/Api/Post/PostHistoryModel.php b/app/Models/Api/Post/PostHistoryModel.php index 61b0bfc..dbe59f7 100644 --- a/app/Models/Api/Post/PostHistoryModel.php +++ b/app/Models/Api/Post/PostHistoryModel.php @@ -44,5 +44,15 @@ class PostHistoryModel extends ApiBaseModel return $this->addItem($aItem); } + //获取最新的历史记录(=当前) + function findLastPostId($post_id,$col = ['*']): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|null + { + return $this->newQuery() + ->where('oid',$post_id) + ->where('method','!=',self::METHOD_DEL) + ->orderBy('created_at','desc') + ->first($col); + } + } diff --git a/app/Models/Api/Wallet/CustomerPostOrderWalletCheckbookModel.php b/app/Models/Api/Wallet/CustomerPostOrderWalletCheckbookModel.php deleted file mode 100644 index 72d3e9a..0000000 --- a/app/Models/Api/Wallet/CustomerPostOrderWalletCheckbookModel.php +++ /dev/null @@ -1,27 +0,0 @@ - '充值', self::TYPE_WITHDRAW_DEC => '提现', @@ -68,6 +71,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel self::TYPE_ADMIN_SUB => '管理员扣款', self::TYPE_TRANSFER_TO_USER_DEC => '转账给用户', self::TYPE_TRANSFER_RECEIVE_ADD => '转账收款', + self::TYPE_ORDER_DISPUTE_FEE_DEC => '纠纷仲裁费用扣除', + self::TYPE_ORDER_DISPUTE_FEE_ADD => '纠纷仲裁费用退还', ]; const STATUS_WAIT = 1; @@ -90,6 +95,117 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel self::SOURCE_PARAMS_SECURITY => '保证金', ]; + function getDelayPayList($datetime, $col = ['*']): \Illuminate\Database\Eloquent\Collection|array + { + return $this->newQuery()->where('status', self::STATUS_DELAY_PAYMENT)->where('delay_payment_time', '<=', $datetime)->limit(100)->get($col); + } + + //纠纷仲裁费用退还 + function typeOrderDisputeFeeAdd($uid, $currency_code, $amount, $remark = null): bool + { + $bean = new CustomerWalletBalanceTransactionBean(); + $bean->setUid($uid); + $bean->setCurrencyCode($currency_code); + $bean->setAmount(abs($amount)); //正数 + $bean->setType(self::TYPE_ORDER_DISPUTE_FEE_ADD); + $bean->setStatus(self::STATUS_SUCCESS); + $bean->setRemark($remark); + try { + DB::beginTransaction(); + //查询用户余额 + $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); + $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); + if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); + $bean->setWalletId($resWalletBalanceModel->id); + $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); + $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); + //新增账变 + $res = $this->addTransaction($bean); + if (!$res) throw new ModelException('addTransaction fail'); + //变更余额 + $res = $oCustomerWalletBalanceModel->addAvailableAmount($bean->getWalletId(), $bean->getAmount()); + if (!$res) throw new ModelException('order dispute fee add fail'); + DB::commit(); + Logs::SuccLog(__FUNCTION__, func_get_args()); + return true; + } catch (\Exception $e) { + DB::rollBack(); + Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); + return false; + } + } + + //纠纷仲裁费用扣除 + function typeOrderDisputeFeeDec($uid, $currency_code, $amount, $remark = null): bool + { + $bean = new CustomerWalletBalanceTransactionBean(); + $bean->setUid($uid); + $bean->setCurrencyCode($currency_code); + $bean->setAmount(-abs($amount)); //账变负数 + $bean->setType(self::TYPE_ORDER_DISPUTE_FEE_DEC); + $bean->setStatus(self::STATUS_SUCCESS); + $bean->setRemark($remark); + try { + DB::beginTransaction(); + //查询用户余额 + $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); + $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); + if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); + if (Math::bcComp($resWalletBalanceModel->available_amount, abs($bean->getAmount())) != -1) throw new ModelException('balance not enough'); + $bean->setWalletId($resWalletBalanceModel->id); + $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); + $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); + //新增账变 + $res = $this->addTransaction($bean); + if (!$res) throw new ModelException('addTransaction fail'); + //变更余额 + $res = $oCustomerWalletBalanceModel->subAvailableAmount($bean->getWalletId(), $bean->getAmount()); + if (!$res) throw new ModelException('order dispute fee dec fail'); + DB::commit(); + Logs::SuccLog(__FUNCTION__, func_get_args()); + return true; + } catch (\Exception $e) { + DB::rollBack(); + Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); + return false; + } + } + + //处理延期账变 + function dealDelayPaymentTransactionCmd(): void + { + $datetimeNow = Times::getNowDateTime(); + $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); + while (true) { + $resList = $this->getDelayPayList($datetimeNow, ['id']); + if ($resList->isEmpty()) { + break; + } + foreach ($resList as $itemId) { + try { + DB::beginTransaction(); + $item = $this->findItem($itemId->id); + $resWalletBalanceModel = $oCustomerWalletBalanceModel->findItem($item->wallet_id); + if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); + $updateItem = [ + 'id' => $item->id, + 'status' => self::STATUS_SUCCESS, + 'updated_at' => Times::getNowDateTime(), + ]; + $res = $this->updateItem($updateItem); + if (!$res) throw new ModelException('updateItem fail'); + $res = $oCustomerWalletBalanceModel->unFrozenAmount($item->wallet_id, $item->amount); + if (!$res) throw new ModelException('unFrozenAmount fail'); + DB::commit(); + Logs::SuccLog(__FUNCTION__, func_get_args()); + } catch (\Exception $e) { + DB::rollBack(); + Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); + } + } + } + } + //转账给用户 function typeTransferToUser($uid, $target_uid, $currency_code, $amount, $remark = null): bool { @@ -310,7 +426,7 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel } //仲裁判罚扣除 - function typeDisputeSub($uid, $currency_code, $amount, $remark = null): bool + function typeDisputeSub($uid, $currency_code, $amount, $target_post_order_dispute_id, $remark = null): bool|int { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); @@ -319,6 +435,7 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel $bean->setType(self::TYPE_DISPUTE_SUB); $bean->setStatus(self::STATUS_SUCCESS); $bean->setRemark($remark); + $bean->setTargetPostOrderDisputeId($target_post_order_dispute_id); try { DB::beginTransaction(); //查询用户余额 @@ -330,8 +447,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //新增账变 - $res = $this->addTransaction($bean); - if (!$res) throw new ModelException('addTransaction fail'); + $resModel = $this->addTransaction($bean); + if (!$resModel) throw new ModelException('addTransaction fail'); //变更余额 //检查余额是否足够 if (Math::bcComp($resWalletBalanceModel->available_amount, abs($bean->getAmount())) != -1) { //从余额中扣除 @@ -346,7 +463,7 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel if (!$res) throw new ModelException('dispute sub fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); - return true; + return $resModel->id; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); @@ -356,7 +473,7 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel } //仲裁判罚增加 - function typeDisputeAdd($uid, $currency_code, $amount, $remark = null): bool + function typeDisputeAdd($uid, $currency_code, $amount, $target_post_order_dispute_id, $remark = null): bool|int { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); @@ -365,6 +482,7 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel $bean->setType(self::TYPE_DISPUTE_ADD); $bean->setStatus(self::STATUS_SUCCESS); $bean->setRemark($remark); + $bean->setTargetPostOrderDisputeId($target_post_order_dispute_id); try { DB::beginTransaction(); //查询用户余额 @@ -375,15 +493,15 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //新增账变 - $res = $this->addTransaction($bean); - if (!$res) throw new ModelException('addTransaction fail'); + $resModel = $this->addTransaction($bean); + if (!$resModel) throw new ModelException('addTransaction fail'); //变更余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $res = $oCustomerWalletBalanceModel->addAvailableAmount($bean->getWalletId(), $bean->getAmount()); if (!$res) throw new ModelException('dispute add fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); - return true; + return $resModel->id; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); diff --git a/app/Tools/Logs.php b/app/Tools/Logs.php index 13e704f..9e27fd3 100644 --- a/app/Tools/Logs.php +++ b/app/Tools/Logs.php @@ -8,12 +8,12 @@ class Logs { static function ErrLog($title, \Exception $e, $params = []): void { - Log::error(self::getTitle($title,'success:'), ['message' => $e->getMessage(), 'trace' => $e->getTrace(), 'params' => $params]); + Log::error(self::getTitle($title,'error:'), ['message' => $e->getMessage(), 'trace' => $e->getTrace(), 'params' => $params]); } static function SuccLog($title, $params = []): void { - Log::error(self::getTitle($title,'error:'), $params); + Log::error(self::getTitle($title,'success:'), $params); } static function getTitle($title,$prefix=''): string diff --git a/app/Tools/Tools.php b/app/Tools/Tools.php index 40ba459..8814074 100644 --- a/app/Tools/Tools.php +++ b/app/Tools/Tools.php @@ -1,10 +1,17 @@ id(); + } //生成随机数 public static function generateRandStr($length = 8) diff --git a/composer.json b/composer.json index 8e99515..6c12671 100644 --- a/composer.json +++ b/composer.json @@ -9,12 +9,13 @@ "license": "MIT", "require": { "php": "^8.1", + "ext-bcmath": "*", "easyswoole/spl": "^2.1", + "godruoyi/php-snowflake": "^3.0", "guzzlehttp/guzzle": "^7.8", "laravel/framework": "^10.10", "laravel/sanctum": "^3.3", - "laravel/tinker": "^2.8", - "ext-bcmath": "*" + "laravel/tinker": "^2.8" }, "require-dev": { "fakerphp/faker": "^1.9.1", diff --git a/composer.lock b/composer.lock index 695d203..551d959 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "779c2c416d83ff65448d583b525c3691", + "content-hash": "8d1357294fac8e18aa387c5c5f295c8e", "packages": [ { "name": "brick/math", @@ -627,6 +627,69 @@ ], "time": "2023-10-12T05:21:21+00:00" }, + { + "name": "godruoyi/php-snowflake", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/godruoyi/php-snowflake.git", + "reference": "bf77419d3ac657ee4e4375d5436ba0c8a7ac8c65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/godruoyi/php-snowflake/zipball/bf77419d3ac657ee4e4375d5436ba0c8a7ac8c65", + "reference": "bf77419d3ac657ee4e4375d5436ba0c8a7ac8c65", + "shasum": "" + }, + "require": { + "php-64bit": ">=8.1" + }, + "require-dev": { + "laravel/pint": "^1.10", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10" + }, + "type": "library", + "autoload": { + "psr-4": { + "Godruoyi\\Snowflake\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Godruoyi", + "email": "g@godruoyi.com" + } + ], + "description": "An ID Generator for PHP based on Snowflake Algorithm (Twitter announced).", + "homepage": "https://github.com/godruoyi/php-snowflake", + "keywords": [ + "Unique ID", + "laravel snowflake", + "order id", + "php snowflake", + "php sonyflake", + "php unique id", + "snowflake algorithm", + "sonyflake", + "unique order id" + ], + "support": { + "issues": "https://github.com/godruoyi/php-snowflake/issues", + "source": "https://github.com/godruoyi/php-snowflake/tree/3.0.0" + }, + "funding": [ + { + "url": "https://images.godruoyi.com/wechat.png", + "type": "custom" + } + ], + "time": "2023-08-28T12:37:25+00:00" + }, { "name": "graham-campbell/result-type", "version": "v1.1.2", @@ -8208,7 +8271,8 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^8.1" + "php": "^8.1", + "ext-bcmath": "*" }, "platform-dev": [], "plugin-api-version": "2.6.0"