CronLogic.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. <?php
  2. namespace App\Http\Logic\Cron;
  3. use App\Exceptions\CommonException;
  4. use App\Http\Bean\Cron\logic\HandleOrderParamBean;
  5. use App\Http\Bean\Util\Jutuike\GetOrderListParamBean;
  6. use App\Http\Bean\Util\Meituan\OrderListParamBean;
  7. use App\Http\Bean\Util\Pdd\Ddk\OrderListIncrementGetParamBean;
  8. use App\Http\Enum\ErrorEnum;
  9. use App\Http\Enum\OrderStatusEnum;
  10. use App\Http\Enum\PlatformTypeEnum;
  11. use App\Http\Logic\BaseLogic;
  12. use App\Http\Logic\Order\OrderLogic;
  13. use App\Http\Utils\BaseUtil;
  14. use App\Http\Utils\Jutuike\JutuikeUtil;
  15. use App\Http\Utils\LoggerFactoryUtil;
  16. use App\Http\Utils\Meituan\MeituanLianmengUtil;
  17. use App\Http\Utils\Pdd\DuoDuoKeUtil;
  18. use App\Http\Utils\WechatAccountUtil;
  19. use App\Models\CategoryModel;
  20. use App\Models\UserCashModel;
  21. use App\Models\UserFinanceModel;
  22. use App\Models\UserModel;
  23. use App\Models\UserOrderCommissionModel;
  24. use App\Models\UserOrderModel;
  25. use App\Models\WechatAccountModel;
  26. use EasyWeChat\Factory;
  27. use Illuminate\Support\Facades\DB;
  28. class CronLogic extends BaseLogic
  29. {
  30. /**
  31. * 获取美团订单
  32. */
  33. public static function meituanOrderslogic()
  34. {
  35. $params = request()->all();
  36. $arr = [
  37. "appkey"=>env("MEITUAN_LIANMENG_KEY"),
  38. "type"=>$params["order_type"],
  39. "startTime"=>time()-$params["minute"]*60,
  40. "endTime"=>time(),
  41. // "startTime"=>strtotime("2021-09-22 11:25:00"),
  42. // "endTime"=>time(),
  43. "page"=>1,
  44. "limit"=>30,
  45. "queryTimeType"=>2,
  46. ];
  47. $instance = new LoggerFactoryUtil(CronLogic::class);
  48. $instance->info("获取订单数据开始");
  49. $bean = new OrderListParamBean($arr);
  50. $res = MeituanLianmengUtil::orderList($bean);
  51. // dd($res);
  52. $instance->info("美团返回数据:".json_encode($res));
  53. $instance->info("订单数量:".$res["total"]);
  54. if($res){
  55. //存在数据,写入订单数据表
  56. if($res["total"]){
  57. $instance->info("订单数据:".json_encode($res));
  58. BaseUtil::sendBaoJing("","获取到订单数量:".$res["total"],"定时获取美团订单");
  59. //处理订单
  60. self::checkOrder($res["dataList"],$params["order_type"]);
  61. //判断订单数量是否大于分页
  62. $pageNum = ceil($res["total"]/100)-1;
  63. if($pageNum){
  64. for ($i=1;$i<=$pageNum;$i++){
  65. $arr["page"]++;
  66. $bean = new OrderListParamBean($arr);
  67. $res = MeituanLianmengUtil::orderList($bean);
  68. if ($res) {
  69. //存在数据,写入订单数据表
  70. if ($res["total"]) {
  71. self::checkOrder($res["dataList"],$params["order_type"]);
  72. }
  73. }
  74. }
  75. }
  76. }
  77. }
  78. }
  79. /**
  80. * 处理订单
  81. */
  82. protected static function checkOrder($orders,$orderType)
  83. {
  84. foreach ($orders as $data) {
  85. switch ($data["status"]) {
  86. case 1://已付款
  87. $orderStatus = OrderStatusEnum::ALREADY_PAY;
  88. break;
  89. case 8://已收货
  90. $orderStatus = OrderStatusEnum::ALREADY_RECEIVE;
  91. break;
  92. case 9://已退款或风控
  93. $orderStatus = OrderStatusEnum::ALREADY_REFUND;
  94. break;
  95. }
  96. $params = [
  97. "spreadSonType" => 0,//订单子类型
  98. "orderNumber" => $data["orderid"],//订单编号
  99. "payTime" => date("Y-m-d H:i:s", $data["paytime"]),//支付时间
  100. "orderPrice" => $data["payprice"] * 100,//订单金额
  101. "orderCommission" => $data["profit"] * 100,//订单佣金
  102. "orderTitle" => $data["smstitle"],//订单标题
  103. "orderRefundPrice" => isset($data["refundprice"]) ? $data["refundprice"] * 100 : 0,//退款金额
  104. "orderRefundTime" => isset($data["refundtime"]) ? date("Y-m-d H:i:s", $data["refundtime"]) : null,//退款时间
  105. "orderRefundCommission" => isset($data["refundprofit"]) ? $data["refundprofit"] : 0,//退款佣金
  106. "orderStatus" => $orderStatus,//订单状态
  107. "orderCouponPrice" => 0,//订单优惠
  108. "productImgUrl" => "https://pic.rmb.bdstatic.com/bjh/f049242a789a22fb1a412bb6418c52e2.jpeg",//商品图片
  109. "spreadType"=>PlatformTypeEnum::PLATFORM_MEITUAN,//订单类型
  110. "userSpreadId"=>$data["sid"],//用户推广位
  111. "platformSpreadId"=>$data["sid"],//平台推广位
  112. "createdAt"=>date("Y-m-d H:i:s", $data["paytime"])
  113. ];
  114. $bean = new HandleOrderParamBean($params);
  115. OrderLogic::handleOrderLogic($bean);
  116. }
  117. }
  118. /**
  119. * 聚推客订单逻辑
  120. */
  121. public static function jutuikeOrdersLogic()
  122. {
  123. $params = request()->all();
  124. $startTime = date("Y-m-d H:i:s",time()-600);
  125. $endTime = date("Y-m-d H:i:s");
  126. if(isset($params["start_time"])){
  127. $startTime = $params["start_time"];
  128. }
  129. if (isset($params["end_time"])){
  130. $endTime= $params["end_time"];
  131. }
  132. $page = 1;
  133. $params = [
  134. "start_time"=>$startTime,
  135. "end_time"=>$endTime,
  136. "query_type"=>2,
  137. "page"=>$page,
  138. "pageSize"=>100
  139. ];
  140. $bean = new GetOrderListParamBean($params);
  141. $data = JutuikeUtil::getOrderList($bean);
  142. $instance = new LoggerFactoryUtil(CronLogic::class);
  143. $instance->info("上游返回数据:".json_encode($data));
  144. if($data["code"]!=1){
  145. //上游错误
  146. return;
  147. }
  148. //判断是否存在订单
  149. $orderLists = $data["data"]["data"];
  150. if(count($orderLists)){
  151. BaseUtil::sendBaoJing("","获取到订单数量:".count($orderLists),"定时获取聚推客订单");
  152. }
  153. foreach ($orderLists as $orderList){
  154. self::handleOrderLogic($orderList);
  155. }
  156. }
  157. public static function handleOrderLogic($orderList)
  158. {
  159. //判断订单状态
  160. switch ($orderList["status"]){
  161. case 0://未付款
  162. $orderStatus = OrderStatusEnum::PRE_PAY;
  163. break;
  164. case 1://已付款
  165. $orderStatus = OrderStatusEnum::ALREADY_PAY;
  166. break;
  167. case 2://待结算
  168. $orderStatus = OrderStatusEnum::ALREADY_RECEIVE;
  169. break;
  170. case 3://已结算
  171. $orderStatus = OrderStatusEnum::ALREADY_FINISH;
  172. break;
  173. case 4://无效订单
  174. $orderStatus = OrderStatusEnum::ALREADY_CANCEL;
  175. break;
  176. }
  177. //获取活动图片
  178. $actImgUrl = CategoryModel::query()
  179. ->where("platform_type",PlatformTypeEnum::PLATFORM_JUTUIKE)
  180. ->where("activity_id",$orderList["act_id"])
  181. ->value("category_img_url");
  182. $params = [
  183. "spreadSonType" => 0,//订单子类型
  184. "orderNumber" => $orderList["order_sn"],//订单编号
  185. "payTime" => $orderList["pay_time"],//支付时间
  186. "orderPrice" => $orderList["order_price"] * 100,//订单金额
  187. "orderCommission" => $orderList["jtk_share_fee"] * 100,//订单佣金
  188. "orderTitle" => $orderList["order_title"],//订单标题
  189. "orderRefundPrice" => 0,//退款金额
  190. "orderRefundTime" => null,//退款时间
  191. "orderRefundCommission" => 0,//退款佣金
  192. "orderStatus" => $orderStatus,//订单状态
  193. "orderCouponPrice" => 0,//订单优惠
  194. "productImgUrl" => $actImgUrl,//商品图片
  195. "spreadType"=>PlatformTypeEnum::PLATFORM_JUTUIKE,//订单类型
  196. "userSpreadId"=>$orderList["sid"],//用户推广位
  197. "platformSpreadId"=>$orderList["sid"],//平台推广位
  198. "createdAt"=>$orderList["create_time"],//订单创建时间
  199. ];
  200. $bean = new HandleOrderParamBean($params);
  201. OrderLogic::handleOrderLogic($bean);
  202. }
  203. /**
  204. * 获取拼多多订单逻辑
  205. */
  206. public static function pddOrdersLogic()
  207. {
  208. $params = [
  209. "startUpdateTime"=>time()-600,
  210. "endUpdateTime"=>time()
  211. ];
  212. $bean = new OrderListIncrementGetParamBean($params);
  213. $res = DuoDuoKeUtil::orderListIncrementGet($bean);
  214. $instance = new LoggerFactoryUtil(CronLogic::class);
  215. $instance->info("上游返回信息:".json_encode($res));
  216. if (isset($res["error_response"])){
  217. return;
  218. }
  219. if($res["order_list_get_response"]["total_count"]){
  220. BaseUtil::sendBaoJing("","获取到订单数量:".$res["order_list_get_response"]["total_count"],"定时获取拼多多订单");
  221. }
  222. //获取数据
  223. $datas = $res["order_list_get_response"]["order_list"];
  224. foreach ($datas as $orderList){
  225. switch ($orderList["order_status"]){
  226. case 0:
  227. //已支付
  228. $orderStatus = OrderStatusEnum::ALREADY_PAY;
  229. break;
  230. case 1:
  231. //已成团
  232. $orderStatus = OrderStatusEnum::ALREADY_PAY;
  233. break;
  234. case 2:
  235. //确认收货
  236. $orderStatus = OrderStatusEnum::ALREADY_RECEIVE;
  237. break;
  238. case 3:
  239. //审核成功
  240. $orderStatus = OrderStatusEnum::ALREADY_RECEIVE;
  241. break;
  242. case 4:
  243. //审核失败(不可提现)
  244. $orderStatus = OrderStatusEnum::ALREADY_CANCEL;
  245. break;
  246. case 5:
  247. //已经结算
  248. $orderStatus = OrderStatusEnum::ALREADY_RECEIVE;
  249. break;
  250. case 10:
  251. //已处罚
  252. $orderStatus = OrderStatusEnum::ALREADY_CANCEL;
  253. break;
  254. }
  255. $params = [
  256. "spreadSonType" => 0,//订单子类型
  257. "orderNumber" => $orderList["order_sn"],//订单编号
  258. "payTime" => date("Y-m-d H:i:s",$orderList["order_pay_time"]),//支付时间
  259. "orderPrice" => $orderList["order_amount"],//订单金额
  260. "orderCommission" => $orderList["promotion_amount"],//订单佣金
  261. "orderTitle" => $orderList["goods_name"],//订单标题
  262. "orderRefundPrice" => 0,//退款金额
  263. "orderRefundTime" => null,//退款时间
  264. "orderRefundCommission" => 0,//退款佣金
  265. "orderStatus" => $orderStatus,//订单状态
  266. "orderCouponPrice" => 0,//订单优惠
  267. "productImgUrl" => "https://pic.rmb.bdstatic.com/bjh/6d9fb4a81eb5fc933da8949854c4fab2.jpeg",//商品图片
  268. "spreadType"=>PlatformTypeEnum::PLATFORM_PINGDUODUO,//订单类型
  269. "userSpreadId"=>$orderList["p_id"],//用户推广位
  270. "platformSpreadId"=>$orderList["p_id"],//平台推广位
  271. "createdAt"=>date("Y-m-d H:i:s",$orderList["order_create_time"]),//订单创建时间
  272. ];
  273. $bean = new HandleOrderParamBean($params);
  274. OrderLogic::handleOrderLogic($bean);
  275. }
  276. }
  277. /**
  278. * 发送用户下单模版
  279. */
  280. public static function sendOrderTemplateLogic()
  281. {
  282. $instance = new LoggerFactoryUtil(CronLogic::class);
  283. //1.新增粉丝通知
  284. $userFans = UserModel::query()
  285. ->where("invite_user_id","<>",0)
  286. ->where("user_notify_status",0)
  287. ->get();
  288. foreach ($userFans as $userFan){
  289. //获取推荐人
  290. $inviteUser = UserModel::findById($userFan->invite_user_id);
  291. if($inviteUser){
  292. try{
  293. //获取公众号实例
  294. $app = WechatAccountUtil::getAppByID($userFan->wechat_account_id);
  295. $data = [
  296. 'touser' => $inviteUser->user_open_id,
  297. 'template_id' => env("WECHAT_FANS_TEMPLATE_URL"),
  298. 'url' => env("WECHAT_FANS_URL"),
  299. 'data' => [
  300. 'first' => "亲,您有新的粉丝",
  301. 'keyword1' => $userFan->user_nickname,
  302. 'keyword2' => $userFan->id+100000,
  303. "remark"=>"粉丝将提供分享佣金,粉丝越多比例越高哦,点击查看详情"
  304. ],
  305. ];
  306. $res = $app->template_message->send($data);
  307. $instance->info("粉丝通知微信返回结果:".json_encode($res));
  308. }catch (\Throwable $exception){
  309. $instance->info("粉丝通知结果异常:".$exception->getMessage());
  310. }
  311. UserModel::query()->where("id",$userFan->id)->update(
  312. [
  313. "user_notify_status"=>1
  314. ]
  315. );
  316. }
  317. }
  318. //2.获取自购已支付且未通知进行模版推送
  319. $orders = UserOrderCommissionModel::query()
  320. ->where("commission_status",0)
  321. ->where("order_commission",">",0)
  322. ->where("user_id","<>",0)
  323. ->where("order_notify_status",0)
  324. ->limit(10)
  325. ->get();
  326. foreach ($orders as $order){
  327. //判断是否自购订单
  328. if($order->user_provider_id){
  329. //反佣订单
  330. $user = UserModel::findById($order->user_id);
  331. if($user){
  332. try{
  333. //获取公众号实例
  334. $app = WechatAccountUtil::getAppByID($user->wechat_account_id);
  335. $tmpOrder = UserOrderModel::query()->where("order_number",$order->order_number)->first();
  336. $privideUser = UserModel::findById($order->user_provider_id);
  337. $data = [
  338. 'touser' => $user->user_open_id,
  339. 'template_id' => env("WECHAT_FANS_ORDER_TEMPLATE_URL"),
  340. 'url' => env("WECHAT_FANS_ORDER_URL"),
  341. 'data' => [
  342. 'first' => "粉丝下单成功通知",
  343. 'keyword1' => $order->order_number,
  344. 'keyword2' => $tmpOrder->product_name,
  345. 'keyword3' => $order->created_at,
  346. 'keyword4' => round($tmpOrder->order_price/100,2)."元",
  347. 'keyword5' => $privideUser->user_nickname,
  348. "remark"=>"您的粉丝有新的订单,分享佣金已产生,3天后结算到您账户中,点击详情跳转粉丝订单"
  349. ],
  350. ];
  351. $res = $app->template_message->send($data);
  352. $instance->info("粉丝下单微信返回结果:".json_encode($res));
  353. }catch (\Throwable $exception){
  354. $instance->info("粉丝下单通知结果异常:".$exception->getMessage());
  355. }
  356. }
  357. }else{
  358. $user = UserModel::findById($order->user_id);
  359. if($user){
  360. try{
  361. //获取公众号实例
  362. $app = WechatAccountUtil::getAppByID($user->wechat_account_id);
  363. $tmpOrder = UserOrderModel::query()->where("order_number",$order->order_number)->first();
  364. $data = [
  365. 'touser' => $user->user_open_id,
  366. 'template_id' => env("WECHAT_ORDER_TEMPLATE_URL"),
  367. 'url' => env("WECHAT_ORDER_URL"),
  368. 'data' => [
  369. 'first' => "下单成功通知",
  370. 'keyword1' => $order->created_at,
  371. 'keyword2' => $tmpOrder->product_name,
  372. 'keyword3' => $order->order_number,
  373. "remark"=>"感谢您的使用,每月20号结算上个月的佣金,将会结算到您的账户中点击详情跳转我的订单"
  374. ],
  375. ];
  376. $res = $app->template_message->send($data);
  377. $instance->info("自购下单微信返回结果:".json_encode($res));
  378. }catch (\Throwable $exception){
  379. $instance->info("自购下单通知结果异常:".$exception->getMessage());
  380. }
  381. }
  382. }
  383. UserOrderCommissionModel::query()->where("id",$order->id)->update(
  384. [
  385. "order_notify_status"=>1
  386. ]
  387. );
  388. }
  389. //3.获取已结算订单,并通知
  390. $completeOrders = UserOrderCommissionModel::query()
  391. ->where("commission_status",1)
  392. ->where("order_commission",">",0)
  393. ->where("user_id","<>",0)
  394. ->where("order_complete_notify_status",0)
  395. ->limit(10)
  396. ->get();
  397. foreach ($completeOrders as $order){
  398. $user = UserModel::findById($order->user_id);
  399. if($user){
  400. try{
  401. //获取公众号实例
  402. $app = WechatAccountUtil::getAppByID($user->wechat_account_id);
  403. $tmpOrder = UserOrderModel::query()->where("order_number",$order->order_number)->first();
  404. $data = [
  405. 'touser' => $user->user_open_id,
  406. 'template_id' => env("WECHAT_COMPLETE_ORDER_TEMPLATE_URL"),
  407. 'url' => env("WECHAT_BALANCE_URL"),
  408. 'data' => [
  409. 'first' => "订单:[".$tmpOrder["order_number"]."]佣金已结算完成",
  410. 'keyword1' => round($order->order_commission/100,2)."元",
  411. 'keyword2' => round($tmpOrder->order_price/100,2)."元",
  412. 'keyword3' => $order->updated_at,
  413. "remark"=>"订单佣金已结算完成,感谢您的使用,点击详情跳转我的账户"
  414. ],
  415. ];
  416. $res = $app->template_message->send($data);
  417. $instance->info("订单结算微信返回结果:".json_encode($res));
  418. }catch (\Throwable $exception){
  419. $instance->info("订单结算通知结果异常:".$exception->getMessage());
  420. }
  421. }
  422. UserOrderCommissionModel::query()->where("id",$order->id)->update(
  423. [
  424. "order_complete_notify_status"=>1
  425. ]
  426. );
  427. }
  428. }
  429. /**
  430. * 结算佣金逻辑(每月的20号18点结算上个月的佣金)
  431. */
  432. public static function settlementOrderCommissionLogic()
  433. {
  434. //获取上个月的开始结束时间
  435. $startTime = date("Y-m-d",strtotime("-1 month"))." 00:00:00";
  436. $endTime = date("Y-m-")."01 00:00:00";
  437. //获取上个月未结算的订单且未退款
  438. UserOrderCommissionModel::query()
  439. ->where("commission_status",0)
  440. ->where("order_commission",">",0)
  441. ->where("user_id","<>",0)
  442. ->where("order_complete_notify_status",0)
  443. ->where("created_at","<",$endTime)
  444. ->chunk(100,function ($orderCommissions){
  445. foreach ($orderCommissions as $orderCommission){
  446. try{
  447. //开启事务
  448. DB::beginTransaction();
  449. //1.修改用户的余额
  450. $user = UserModel::query()->lock(true)->find($orderCommission["user_id"]);
  451. if($user){
  452. $userRes = UserModel::query()
  453. ->where("id",$orderCommission["user_id"])
  454. ->increment("user_balance",$orderCommission["order_commission"]);
  455. if(!$userRes){
  456. DB::rollBack();
  457. throw new CommonException(ErrorEnum::ERROR_SYSTEM);
  458. }
  459. //2.添加用户流水记录
  460. $logRes = UserFinanceModel::query()
  461. ->insert(
  462. [
  463. "user_id"=>$orderCommission["id"],
  464. "order_number"=>$orderCommission["order_number"],
  465. "user_before_balance"=>$user["user_balance"],
  466. "user_after_balance"=>$orderCommission["order_commission"]+$user["user_balance"],
  467. "finance_balance"=>$orderCommission["order_commission"],
  468. "finance_remark"=>"订单佣金结算",
  469. "finance_type"=>1,
  470. "finance_number"=>uniqid("fbt-"),
  471. "created_at"=>date("Y-m-d H:i:s"),
  472. "updated_at"=>date("Y-m-d H:i:s")
  473. ]
  474. );
  475. if(!$logRes){
  476. DB::rollBack();
  477. throw new CommonException(ErrorEnum::ERROR_SYSTEM);
  478. }
  479. //3.修改佣金记录为已结算
  480. $commissionRes = UserOrderCommissionModel::query()
  481. ->where("id",$orderCommission["id"])
  482. ->update(
  483. [
  484. "commission_status"=>1,
  485. "updated_at"=>date("Y-m-d H:i:s")
  486. ]
  487. );
  488. if(!$commissionRes){
  489. DB::rollBack();
  490. throw new CommonException(ErrorEnum::ERROR_SYSTEM);
  491. }
  492. DB::commit();
  493. }
  494. }catch (\Throwable $exception){}
  495. }
  496. });
  497. }
  498. /**
  499. * 处理提现打款逻辑
  500. */
  501. public static function transferFinanceLogic()
  502. {
  503. $account = WechatAccountModel::query()
  504. ->where("wechat_app_code","fanbuting")
  505. ->first();
  506. $config = [
  507. "app_id"=>$account["wechat_app_id"],
  508. "mch_id"=>$account["account_mch_id"],
  509. "key"=>$account["account_key"],
  510. "cert_path"=>$account["account_cert_path"],
  511. "key_path"=>$account["account_key_path"]
  512. ];
  513. $app = Factory::payment($config);
  514. //获取已审核且未打款的提现记录
  515. $cashLogs = UserCashModel::query()
  516. ->where("check_status",2)
  517. ->where("cash_status",0)
  518. ->get();
  519. if(!$cashLogs){
  520. return ;
  521. }
  522. //将打款记录修改为执行中
  523. $logIds = [];
  524. foreach ($cashLogs as $cashLog){
  525. $logIds[] = $cashLog["id"];
  526. }
  527. UserCashModel::query()
  528. ->whereIn("id",$logIds)
  529. ->update(
  530. [
  531. "cash_status"=>1
  532. ]
  533. );
  534. foreach ($cashLogs as $cashLog){
  535. //1.获取用户的openId
  536. $user = UserModel::query()->find($cashLog["user_id"]);
  537. if($user){
  538. $res = $app->transfer->toBalance(
  539. [
  540. "partner_trade_no"=>$cashLog["cash_order_number"],
  541. "openid"=>$user["user_open_id"],
  542. "check_name"=>"NO_CHECK",//不校验姓名
  543. "re_user_name"=>"",//真实姓名
  544. "amount"=>$cashLog["cash_money"],
  545. "desc"=>"用户提现"
  546. ]
  547. );
  548. //判断是否支付成功
  549. if($res["return_code"]=="SUCCESS" && $res["result_code"]=="SUCCESS"){
  550. UserCashModel::query()
  551. ->where("id",$cashLog["id"])
  552. ->update(
  553. [
  554. "cash_status"=>2,
  555. "upstream_response"=>json_encode($res),
  556. "cash_receive_at"=>date("Y-m-d H:i:s")
  557. ]
  558. );
  559. }else{
  560. //打款失败
  561. UserCashModel::query()
  562. ->where("id",$cashLog["id"])
  563. ->update(
  564. [
  565. "cash_status"=>3,
  566. "upstream_response"=>json_encode($res)
  567. ]
  568. );
  569. }
  570. }
  571. }
  572. }
  573. /**
  574. * 打款失败退款逻辑
  575. */
  576. public static function callbackCashLogic()
  577. {
  578. //获取已审核且未打款的提现记录
  579. $cashLogs = UserCashModel::query()
  580. ->where("callback_status",0)
  581. ->where(function ($query){
  582. $query->where("check_status",3)
  583. ->orWhere("cash_status",3);
  584. })
  585. ->get();
  586. if(!$cashLogs){
  587. return;
  588. }
  589. foreach ($cashLogs as $cashLog){
  590. DB::beginTransaction();
  591. //获取用户
  592. $user = UserModel::query()->lock(true)->find($cashLog["user_id"]);
  593. //1.用户金额增加
  594. $userRes = UserModel::query()
  595. ->where("id",$user["user_id"])
  596. ->increment("user_balance",$cashLog["cash_money"]);
  597. if(!$userRes){
  598. DB::rollBack();
  599. break;
  600. }
  601. //2.添加流水记录
  602. $financeRes = UserFinanceModel::query()->insert(
  603. [
  604. "user_id"=>$cashLog["user_id"],
  605. "user_before_balance"=>$user["user_balance"],
  606. "user_after_balance"=>$user["user_balance"]+$cashLog["cash_money"],
  607. "finance_balance"=>$cashLog["cash_money"],
  608. "finance_remark"=>"提现失败退回,原提现记录ID为:".$cashLog["id"],
  609. "finance_type"=>1,
  610. "finance_number"=>BaseUtil::getOrderNumber(),
  611. "created_at"=>date("Y-m-d H:i:s"),
  612. "updated_at"=>date("Y-m-d H:i:s"),
  613. ]
  614. );
  615. if(!$financeRes){
  616. DB::rollBack();
  617. break;
  618. }
  619. //3.修改提现记录为退款成功
  620. $cashRes = UserCashModel::query()
  621. ->where("id",$cashLog["id"])
  622. ->update([
  623. "callback_status"=>1
  624. ]);
  625. if(!$cashRes){
  626. DB::rollBack();
  627. break;
  628. }
  629. DB::commit();
  630. }
  631. }
  632. }