From ce599e76a4307495dd13096cb028d5a772336292 Mon Sep 17 00:00:00 2001
From: chenbo <709206448@qq.com>
Date: Sat, 9 Sep 2023 19:59:50 +0800
Subject: [PATCH] =?UTF-8?q?update:=E5=85=AC=E5=8F=B8=E6=8F=90=E7=8E=B0?=
 =?UTF-8?q?=E6=94=B9=E9=80=A0,app=E7=AB=AF=E6=96=B0=E5=A2=9E=E7=94=A8?=
 =?UTF-8?q?=E6=88=B7=E5=BD=93=E5=89=8D=E5=8F=AF=E6=8F=90=E7=8E=B0=E9=87=91?=
 =?UTF-8?q?=E9=A2=9D=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=90=8E=E5=8F=B0=E6=96=B0?=
 =?UTF-8?q?=E5=A2=9E=E6=8F=90=E7=8E=B0=E5=AE=A1=E6=A0=B8=E6=8E=A5=E5=8F=A3?=
 =?UTF-8?q?=EF=BC=8C=E6=A0=B9=E6=8D=AE=E5=91=A8=E6=9C=9F=E5=86=85=E5=8F=AF?=
 =?UTF-8?q?=E6=8F=90=E7=8E=B0=E9=87=91=E9=A2=9D=E5=81=9A=E6=89=A3=E9=99=A4?=
 =?UTF-8?q?=E5=85=AC=E5=8F=B8=E9=87=91=E9=A2=9D=E5=92=8C=E7=94=A8=E6=88=B7?=
 =?UTF-8?q?=E9=87=91=E9=A2=9D=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../controller/finance/WithdrawController.php |  21 +++
 app/api/controller/UserController.php         |  16 +++
 app/api/logic/UserLogic.php                   |  11 +-
 app/common/enum/user/AccountLogEnum.php       |   3 +
 app/common/logic/finance/WithdrawLogic.php    | 125 ++++++++++++++++++
 .../model/company/CompanyAccountLog.php       |   5 +
 6 files changed, 179 insertions(+), 2 deletions(-)
 create mode 100644 app/common/logic/finance/WithdrawLogic.php

diff --git a/app/adminapi/controller/finance/WithdrawController.php b/app/adminapi/controller/finance/WithdrawController.php
index bb70631a8..b5bb59b8b 100644
--- a/app/adminapi/controller/finance/WithdrawController.php
+++ b/app/adminapi/controller/finance/WithdrawController.php
@@ -3,7 +3,9 @@
 namespace app\adminapi\controller\finance;
 
 use app\adminapi\controller\BaseAdminController;
+use app\common\logic\finance\WithdrawLogic;
 use app\common\model\user\Withdraw;
+use think\Exception;
 
 class WithdrawController extends BaseAdminController
 {
@@ -37,4 +39,23 @@ class WithdrawController extends BaseAdminController
         return $this->success('操作成功', [], 1, 1);
     }
 
+    /**
+     * 提现申请审核
+     */
+    public function audit()
+    {
+        try {
+            $params = $this->request->param();
+            if (empty($params['transfer_voucher'])) {
+                return $this->fail('请上传转账凭证');
+            }
+            $re = WithdrawLogic::audit($params);
+            if (!$re) {
+                return $this->fail(WithdrawLogic::getError());
+            }
+            return $this->success('操作成功', [], 1, 1);
+        } catch (Exception $exception) {
+            return $this->fail($exception->getMessage());
+        }
+    }
 }
\ No newline at end of file
diff --git a/app/api/controller/UserController.php b/app/api/controller/UserController.php
index 915a95c47..58ed00fcc 100755
--- a/app/api/controller/UserController.php
+++ b/app/api/controller/UserController.php
@@ -14,6 +14,7 @@
 namespace app\api\controller;
 
 
+use app\adminapi\logic\ConfigLogic;
 use app\api\logic\UserLogic;
 use app\common\logic\UserLogic as CommonUserLogic;
 use app\api\validate\PasswordValidate;
@@ -21,7 +22,9 @@ use app\api\validate\SetUserInfoValidate;
 use app\api\validate\UserValidate;
 use app\common\logic\contract\ContractLogic;
 use app\common\model\contract\Contract;
+use app\common\model\dict\DictData;
 use app\common\model\user\User;
+use app\common\model\user\UserAccountLog;
 use Common;
 use think\facade\Db;
 
@@ -156,6 +159,19 @@ class UserController extends BaseApiController
         return $this->fail(UserLogic::getError());
     }
 
+    /**
+     * 获取用户当前可提现的周期以及可提现的金额
+     */
+    public function getCurrCycleWithdraw()
+    {
+        $userInfo = User::find(['id' => $this->userId]);
+        // 数据字典  提前周期 单位:天数
+        $dictData = ConfigLogic::getDictByType('withdraw_cycle');
+        $endCycle = strtotime(date('Y-m-d', strtotime("-{$dictData['withdraw_cycle'][0]['value']} day")));
+        // 计算公司周期内所有用户已完成的 变动类型为任务收益金额增加 动作为增加的 未提现状态 的变动金额之和
+        $currTotalWithdrawMoney = UserAccountLog::where(['company_id'=>$userInfo['company_id'], 'action'=>1, 'status'=>1, 'is_withdraw'=>0, 'change_type'=>202])->where('create_time','<', $endCycle)->sum('change_amount');
+        return $this->success('成功', ['end_cycle'=>$endCycle, 'user_currrent_total_withdraw_money'=>$currTotalWithdrawMoney], 1, 1);
+    }
     public function withdraw()
     {
         $params = $this->request->param();
diff --git a/app/api/logic/UserLogic.php b/app/api/logic/UserLogic.php
index 4dcd64aa4..0644e31a8 100755
--- a/app/api/logic/UserLogic.php
+++ b/app/api/logic/UserLogic.php
@@ -306,6 +306,12 @@ class UserLogic extends BaseLogic
                 throw new DataNotFoundException('用户不存在');
             }
 
+            // 是否有在途的提现申请
+            $withdraw = Withdraw::where(['user_id'=>$params['user_id'], 'status'=>0])->find();
+            if (!empty($withdraw)) {
+                throw new ValidateException('您已有一笔待审核的提现申请');
+            }
+
             // 校验提现金额
             if ($params['amount'] <= 0) {
                 throw new ValidateException('提现金额错误');
@@ -322,13 +328,14 @@ class UserLogic extends BaseLogic
             $withdraw->admin_id = $user['admin_id'];
             $withdraw->order_sn = $withdraw->buildOrderSn();
             $withdraw->amount = $params['amount'];
+            $withdraw->transfer_end_cycel = $params['transfer_end_cycel'];
             $withdraw->create_time = time();
             $withdraw->update_time = time();
             $withdraw->save();
 
             // 扣除余额
-            $user->user_money = $user['user_money'] - $params['amount'];
-            $user->save();
+//            $user->user_money = $user['user_money'] - $params['amount'];
+//            $user->save();
 
             Db::commit();
             return true;
diff --git a/app/common/enum/user/AccountLogEnum.php b/app/common/enum/user/AccountLogEnum.php
index de2a2f207..4f9524801 100755
--- a/app/common/enum/user/AccountLogEnum.php
+++ b/app/common/enum/user/AccountLogEnum.php
@@ -47,6 +47,7 @@ class AccountLogEnum
      */
     const UM_DEC_ADMIN = 100;
     const UM_DEC_RECHARGE_REFUND = 101;
+    const UM_DEC_WITHDRAW = 102; // 提现
 
     /**
      * 用户余额增加类型
@@ -63,6 +64,7 @@ class AccountLogEnum
     const UM_DEC = [
         self::UM_DEC_ADMIN,
         self::UM_DEC_RECHARGE_REFUND,
+        self::UM_DEC_WITHDRAW
     ];
 
 
@@ -115,6 +117,7 @@ class AccountLogEnum
             self::UM_INC_TASK => '任务收益金额增加',
             self::UM_INC_TASKUSER => '任务账户余额增加',
             self::UM_DEC_RECHARGE_REFUND => '充值订单退款减少余额',
+            self::UM_DEC_WITHDRAW => '提现减少余额'
         ];
         if ($flag) {
             return $desc;
diff --git a/app/common/logic/finance/WithdrawLogic.php b/app/common/logic/finance/WithdrawLogic.php
new file mode 100644
index 000000000..a6018150f
--- /dev/null
+++ b/app/common/logic/finance/WithdrawLogic.php
@@ -0,0 +1,125 @@
+<?php
+
+namespace app\common\logic\finance;
+
+use app\common\enum\user\AccountLogEnum;
+use app\common\logic\BaseLogic;
+use app\common\model\Company;
+use app\common\model\company\CompanyAccountLog;
+use app\common\model\user\User;
+use app\common\model\user\UserAccountLog;
+use app\common\model\user\Withdraw;
+use think\Exception;
+use think\facade\Db;
+use think\facade\Log;
+
+class WithdrawLogic extends BaseLogic
+{
+    public static function audit($params)
+    {
+        try {
+            $withDrawInfo = Withdraw::find(['id'=>$params['id']]);
+            Log::info(['提现申请审核-申请单', $withDrawInfo]);
+            if (empty($withDrawInfo)) {
+                throw new Exception('数据不存在');
+            }
+            if ($withDrawInfo->status !== 0) {
+                throw new Exception('状态异常,当前申请已审核');
+            }
+
+            $userInfo = User::find(['id'=>$withDrawInfo['user_id']]);
+            Log::info(['提现申请审核-申请人账户', $userInfo]);
+            if (empty($userInfo)) {
+                throw new Exception('账户异常,提现账户不存在');
+            }
+            if ($userInfo['admin_id'] === 0) {
+                throw new Exception('账户异常,该账户没有提现权限');
+            }
+            $companyInfo = Company::find($userInfo['company_id']);
+            Log::info(['提现申请审核-公司', $userInfo]);
+            if (empty($companyInfo)) {
+                throw new Exception('账户异常,提现账户没有关联公司');
+            }
+
+            // 拒绝通过审核,记录备注原因
+            if ($params['status'] == 2) {
+                Withdraw::where(['id'=>$withDrawInfo['id']])->update(['status'=>2, 'deny_desc'=>$params['deny_desc']]);
+                return true;
+            }
+
+            Db::startTrans();
+            $endCycle = $withDrawInfo['transfer_end_cycel']; // 提现周期截止时间戳
+
+            /**
+             * 1.扣除 公司账户余额 和 添加公司账户余额变动记录
+             * 2.扣除公司内用户的余额(在本次提现周期内增加的金额总和)和用户账户变动记录,并且将用户周期内的账户变动记录变更为已提现状态
+             *
+             */
+
+            // 1.扣除公司账户余额
+            $amount = $withDrawInfo['amount']; // 提现金额
+            $leftMoney = bcsub($companyInfo['company_money'], $amount); // 提现后剩余金额
+            if ($leftMoney < 0) {
+                throw new Exception('公司账户余额不足');
+            }
+            $companyInfo->save(['company_money'=>$leftMoney]);
+
+            $companyAccountLog = [
+                'sn' => generate_sn(UserAccountLog::class, 'sn', 20),
+                'company_id' => $companyInfo['id'],
+                'change_object' => CompanyAccountLog::TASK, //变动对象
+                'change_type' => CompanyAccountLog::WITHDRAW_DEC_DEPOSIT, //变动类型
+                'action' => CompanyAccountLog::DEC, //1-增加 2-减少
+                'left_amount' => $leftMoney, //变动后数量
+                'change_amount' => $amount, //变动数量
+                'remark' => '减少原因:提现',
+                'status' => 1,
+            ];
+            // 添加公司账户余额变动记录
+            CompanyAccountLog::create($companyAccountLog);
+
+            // 2.扣除公司内用户在本次提现周期内增加的金额总和 和 用户账户变动记录,并且将周期内的用户的账户变动记录变更为已提现状态
+            $companyUserList = User::where(['company_id'=>$companyInfo['id']])->select();
+            foreach ($companyUserList as $user) {
+                $tempUserMoneySycleTotal = 0;
+                $tempUserLeftMoney = 0;
+                // 本次提现周期内增加的金额总和    周期内用户状态已完成的 变动类型为任务收益金额增加 动作为增加 未提现状态 的变动金额之和
+                $tempUserMoneySycleTotal = UserAccountLog::where(['user_id'=>$user->id, 'status'=>1, 'action'=>1, 'change_type'=>202, 'is_withdraw'=>0])->where('create_time','<', $endCycle)->sum('change_amount');
+                $tempUserLeftMoney = bcsub($user->user_money,$tempUserMoneySycleTotal);
+                if( $tempUserLeftMoney < 0 ){
+                    throw new Exception('账户异常,用户余额不足,user_id:'.$user->id.",扣除金额:".$tempUserMoneySycleTotal);
+                }
+                // 扣除用户余额
+                $user->save(['user_money'=>$tempUserLeftMoney]);
+                // 用户账户变动记录
+                $data = [
+                    'sn' => generate_sn(UserAccountLog::class, 'sn', 20),
+                    'user_id' => $user->id,
+                    'company_id'=> $user->company_id,
+                    'change_object' => AccountLogEnum::UM,
+                    'change_type' => AccountLogEnum::UM_DEC_WITHDRAW,
+                    'action' => AccountLogEnum::DEC,
+                    'left_amount' => $tempUserLeftMoney,
+                    'change_amount' => $tempUserMoneySycleTotal,
+                    'source_sn' => '',
+                    'remark' => '减少原因:公司提现',
+                    'extra' => '',
+                    'status'=> 1,
+                    'is_withdraw'=> 1
+                ];
+                UserAccountLog::create($data);
+                // 将用户周期内的账户变动记录变更为已提现状态
+                UserAccountLog::where(['user_id'=>$user->id, 'status'=>1, 'action'=>1, 'change_type'=>202, 'is_withdraw'=>0])->where('create_time','<', $endCycle)->update(['is_withdraw'=>1]);
+            }
+            // 更新状态,保存转账凭证
+            Withdraw::where(['id'=>$withDrawInfo['id']])->update(['status'=>3, 'transfer_voucher'=>$params['transfer_voucher']]);
+            Db::commit();
+            return true;
+        } catch (Exception $exception) {
+            Db::rollback();
+            self::setError($exception->getMessage());
+            return false;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/app/common/model/company/CompanyAccountLog.php b/app/common/model/company/CompanyAccountLog.php
index 21b83c3e5..378ae3c45 100644
--- a/app/common/model/company/CompanyAccountLog.php
+++ b/app/common/model/company/CompanyAccountLog.php
@@ -66,6 +66,11 @@ class CompanyAccountLog extends BaseModel
      */
     const SHAREHOLDER_DEC_DEPOSIT = 101;
 
+    /**
+     * 提现
+     */
+    const WITHDRAW_DEC_DEPOSIT = 102;
+
     /**
      * 用户余额增加类型
      */