CronLogic.php 31 KB

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