Withdraw.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <?php
  2. declare (strict_types = 1);
  3. namespace app\api\controller;
  4. use app\api\model\User;
  5. use app\api\model\user\UserIdcards;
  6. use app\api\model\user\Withdraw as WithdrawModel;
  7. use app\api\service\User as UserService;
  8. use app\common\model\store\Setting as SettingModel;
  9. use think\facade\Db;
  10. use app\common\library\helper;
  11. /**
  12. * 提现管理
  13. * Class Withdraw
  14. * @package app\api
  15. */
  16. class Withdraw extends Controller
  17. {
  18. /**
  19. * 提现列表
  20. */
  21. public function list()
  22. {
  23. $params = $this->request->param();
  24. $model = new WithdrawModel;
  25. $list = $model->getList($params);
  26. return $this->renderSuccess(compact('list'));
  27. }
  28. /**
  29. * 提现详情
  30. * @param $id 记录id
  31. */
  32. public function detail($id = 0)
  33. {
  34. $userId = UserService::getCurrentLoginUserId();
  35. $detail = WithdrawModel::where('id', $id)->where('user_id', $userId)->find();
  36. if (empty($detail)) {
  37. return $this->renderError('参数无效');
  38. }
  39. return $this->renderSuccess(compact('detail'));
  40. }
  41. public function apply0()
  42. {
  43. $user = UserService::getCurrentLoginUser(true);
  44. $args = $this->postData();
  45. if (empty($args['amount'])) {
  46. return $this->renderError('提现金额不能为空');
  47. }
  48. $args['create_time'] = date("Y-m-d H:i:s", time());
  49. $args['user_id'] = $user->user_id;
  50. $args['transaction_no'] = WithdrawModel::makeTransactionNo();
  51. $args['tx_account'] = $user->mobile;
  52. $args['real_name'] = '';
  53. $args['remark'] = '佣金提现';
  54. $args['transaction_type'] = 2; // 提现方式 1-支付宝 2-微信
  55. if (empty($user->open_id)) {
  56. return $this->renderError('您尚未绑定微信,请绑定后重试');
  57. }
  58. if ($args['amount'] <= 0) {
  59. return $this->renderError('提现金额不能为空');
  60. }
  61. if ($args['amount'] > $user->ktxyj_amount) {
  62. return $this->renderError('输入金额大于可提现佣金余额,无法提现,请重新输入');
  63. }
  64. // 判断用户是否当日提现次数超过10次,大于10次提示“您今日提现过于频繁,请次日再来~”
  65. $dayCount = WithdrawModel::where('user_id', $args['user_id'])
  66. ->whereBetween('create_time', [date('Y-m-d').' 00:00:00', date('Y-m-d').' 23:59:59'])
  67. ->count();
  68. if ($dayCount > 10) {
  69. return $this->renderError('您今日提现过于频繁,请次日再来~');
  70. }
  71. // 单次提现金额不能小于0.3元
  72. if ($args['amount'] < 0.3) {
  73. return $this->renderError('最低提现金额为0.3元');
  74. }
  75. // 判断用户是否当日提现金额超过5000元,当日累计申请提现(含本次)大于5000元时提示“您今日累计提现数值较大,请次日再来~”
  76. $dayAmount = WithdrawModel::where('user_id', $args['user_id'])
  77. ->whereBetween('create_time', [date('Y-m-d').' 00:00:00', date('Y-m-d').' 23:59:59'])
  78. ->sum('amount');
  79. if ($dayAmount + $args['amount'] > 5000) {
  80. return $this->renderError('您今日累计提现数值较大,请次日再来');
  81. }
  82. // 佣金免打税区间 佣金最低提现额度 佣金最高提现额度
  83. $withdrawSetting = SettingModel::getItem('withdrawal');
  84. // 获取用户年累计提现金额
  85. $yearYjAmount = WithdrawModel::where('user_id', $args['user_id'])
  86. ->whereBetween('pay_time',[date('Y').'-01-01 00:00:00', date('Y').'-12-31 23:59:59'])
  87. ->where('pay_state', 1)
  88. ->sum('amount');
  89. if ($withdrawSetting['free_tax_max'] > 0) {
  90. if ($yearYjAmount + $args['amount'] < $withdrawSetting['free_tax_max']) {
  91. $args['tax'] = 0;
  92. }
  93. else{
  94. $args['tax'] = $withdrawSetting['tax_ratio'] > 0 ? helper::bcadd($withdrawSetting['tax_ratio'] / 100 * $args['amount'],0,4) : 0;
  95. }
  96. } else {
  97. $args['tax'] = $withdrawSetting['tax_ratio'] > 0 ? helper::bcadd($withdrawSetting['tax_ratio'] / 100 * $args['amount'],0,4) : 0;
  98. }
  99. if ($withdrawSetting['withdraw_min'] > 0 && $args['amount'] < $withdrawSetting['withdraw_min']) {
  100. return $this->renderError('提现金额不能小于最低提现额度');
  101. }
  102. if ($withdrawSetting['withdraw_max'] > 0 && $args['amount'] > $withdrawSetting['withdraw_max']) {
  103. return $this->renderError('提现金额不能超过最高提现额度');
  104. }
  105. Db::startTrans();
  106. try {
  107. User::where('user_id', $args['user_id'])->update([
  108. 'ktxyj_amount' => $user->ktxyj_amount-$args['amount'],
  109. 'frozen_yj_amount' => $user->frozen_yj_amount+$args['amount'],
  110. ]);
  111. $userWithdraw = WithdrawModel::create($args);
  112. Db::commit();
  113. return $this->renderSuccess($userWithdraw->toArray(), '提交成功');
  114. } catch (\Exception $e) {
  115. Db::rollback();
  116. return $this->renderError('提交失败');
  117. }
  118. }
  119. public function apply()
  120. {
  121. $user = UserService::getCurrentLoginUser(true);
  122. $args = $this->postData();
  123. if (empty($args['amount'])) {
  124. return $this->renderError('提现金额不能为空');
  125. }
  126. $flag = UserIdcards::checkUserHasIdcard($user->user_id);
  127. if ($flag == false){
  128. return $this->renderSuccess(['needVerify'=>true],'请先完成实名认证');
  129. }
  130. $args['create_time'] = date("Y-m-d H:i:s", time());
  131. $args['user_id'] = $user->user_id;
  132. $args['transaction_no'] = WithdrawModel::makeTransactionNo();
  133. $args['tx_account'] = $user->mobile;
  134. $args['real_name'] = '';
  135. $args['remark'] = '佣金提现';
  136. $args['transaction_type'] = 2; // 提现方式 1-支付宝 2-微信
  137. if (empty($user->open_id)) {
  138. return $this->renderError('您尚未绑定微信,请绑定后重试');
  139. }
  140. if ($args['amount'] <= 0) {
  141. return $this->renderError('提现金额不能为空');
  142. }
  143. if ($args['amount'] > $user->ktxyj_amount) {
  144. return $this->renderError('输入金额大于可提现佣金余额,无法提现,请重新输入');
  145. }
  146. //待审核or已审核通过和未打款
  147. $withdrawing = WithdrawModel::where('user_id', $args['user_id'])
  148. ->where(function ($q){
  149. $q->where(function ($q){
  150. $q->where(['audit'=>1,'pay_state'=>0]);
  151. })->whereOr(function ($q){
  152. $q->where('audit',0);
  153. });
  154. })->find();
  155. if (!empty($withdrawing)) {
  156. return $this->renderError('您的提现正在审核中,请稍后再试');
  157. }
  158. // 判断用户是否当日提现次数超过10次,大于10次提示“您今日提现过于频繁,请次日再来~”
  159. $dayCount = WithdrawModel::where('user_id', $args['user_id'])
  160. ->whereBetween('create_time', [date('Y-m-d').' 00:00:00', date('Y-m-d').' 23:59:59'])
  161. ->count();
  162. if ($dayCount > 10) {
  163. return $this->renderError('您今日提现过于频繁,请次日再来~');
  164. }
  165. // 单次提现金额不能小于0.3元
  166. if ($args['amount'] < 0.3) {
  167. return $this->renderError('最低提现金额为0.3元');
  168. }
  169. // 判断用户是否当日提现金额超过5000元,当日累计申请提现(含本次)大于5000元时提示“您今日累计提现数值较大,请次日再来~”
  170. $dayAmount = WithdrawModel::where('user_id', $args['user_id'])
  171. ->whereBetween('create_time', [date('Y-m-d').' 00:00:00', date('Y-m-d').' 23:59:59'])
  172. ->sum('amount');
  173. //todo 5000要与商户平台保持一致
  174. if ($dayAmount + $args['amount'] > 5000) {
  175. return $this->renderError('您今日累计提现数值较大,请次日再来');
  176. }
  177. // 佣金免打税区间 佣金最低提现额度 佣金最高提现额度
  178. $withdrawSetting = SettingModel::getItem('withdrawal');
  179. // 获取用户年累计提现金额
  180. if ($withdrawSetting['withdraw_min'] > 0 && $args['amount'] < $withdrawSetting['withdraw_min']) {
  181. return $this->renderError('提现金额不能小于最低提现额度');
  182. }
  183. if ($withdrawSetting['withdraw_max'] > 0 && $args['amount'] > $withdrawSetting['withdraw_max']) {
  184. return $this->renderError('提现金额不能超过最高提现额度');
  185. }
  186. $currYearMonth = intval(date('Ym'));
  187. //本月累计提现金额
  188. $x = $this->getCurrMonthAmount($args['user_id'],$args['amount'],$currYearMonth);
  189. $args['amount_sum_monthly'] = $x;
  190. //本次需缴纳税费
  191. $taxArr = $this->getCurrWithdrawTax($args['user_id'],$x,$currYearMonth);
  192. if ($taxArr['currTax'] < 0 ){
  193. return $this->renderError('信息异常,请重试');
  194. }
  195. $args['tax'] = $taxArr['currTax'];
  196. //本月累计缴纳税费
  197. $args['tax_sum_monthly'] = bcadd(strval($taxArr['currTax']),strval($taxArr['hasTaxed']),2);
  198. $args['year_month'] = $currYearMonth;
  199. Db::startTrans();
  200. try {
  201. User::where('user_id', $args['user_id'])->update([
  202. 'ktxyj_amount' => $user->ktxyj_amount - $args['amount'],
  203. 'frozen_yj_amount' => $user->frozen_yj_amount + $args['amount'],
  204. ]);
  205. $userWithdraw = WithdrawModel::create($args);
  206. Db::commit();
  207. return $this->renderSuccess($userWithdraw->toArray(), '提交成功');
  208. } catch (\Exception $e) {
  209. Db::rollback();
  210. return $this->renderError('提交失败');
  211. }
  212. }
  213. /**
  214. * 计算当前提现金额应缴个人所得税
  215. * @return array|\think\response\Json
  216. * @throws \app\common\exception\BaseException
  217. */
  218. public function calTempTax(){
  219. $args = $this->postData();
  220. if (empty($args['amount'])) {
  221. return $this->renderError('提现金额不能为空');
  222. }
  223. $userId = UserService::getCurrentLoginUserId();
  224. $currYearMonth = intval(date('Ym'));
  225. //本月累计提现金额
  226. $x = $this->getCurrMonthAmount($userId,$args['amount'],$currYearMonth);
  227. log_record('x::'.$x,'debug');
  228. $currTax = $this->getCurrWithdrawTax($userId,$x,$currYearMonth)['currTax'];
  229. log_record('currTax::'.$currTax,'debug');
  230. return $this->renderSuccess(["tax"=>$currTax]);
  231. }
  232. //本月累计提现金额(含本次)
  233. private function getCurrMonthAmount($userId,$amount,$currYearMonth){
  234. $yearYjAmount = WithdrawModel::where('user_id', $userId)
  235. ->where('year_month',$currYearMonth)
  236. ->where('pay_state', 1)
  237. ->sum('amount');
  238. //本月累计提现金额
  239. return bcadd(strval($yearYjAmount),strval($amount),4);
  240. }
  241. /**
  242. * 本次提现应缴个人所得税
  243. * @param $userId
  244. * @param $x
  245. * @param $currYearMonth
  246. * @return array
  247. */
  248. private function getCurrWithdrawTax($userId,$x,$currYearMonth){
  249. $hasTaxed = WithdrawModel::where('user_id', $userId)
  250. ->where('year_month',$currYearMonth)
  251. ->where('pay_state', 1)
  252. ->sum('tax');
  253. log_record('$hasTaxed::'.$hasTaxed,'debug');
  254. $currTax = WithdrawModel::calculatorTax($x,$hasTaxed);
  255. return ['hasTaxed'=>$hasTaxed,'currTax'=>$currTax];
  256. }
  257. }