OrderService.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847
  1. <?php
  2. namespace App\Services\Client;
  3. use App\Models\AgentConfig;
  4. use App\Models\AgentInfo;
  5. use App\Models\CoachConfig;
  6. use App\Models\CoachSchedule;
  7. use App\Models\CoachUser;
  8. use App\Models\Coupon;
  9. use App\Models\MemberUser;
  10. use App\Models\Order;
  11. use App\Models\OrderGrabRecord;
  12. use App\Models\OrderRecord;
  13. use App\Models\Project;
  14. use App\Models\SysConfig;
  15. use App\Models\User;
  16. use App\Models\WalletRefundRecord;
  17. use Exception;
  18. use Illuminate\Support\Facades\Auth;
  19. use Illuminate\Support\Facades\DB;
  20. use Illuminate\Support\Facades\Log;
  21. class OrderService
  22. {
  23. protected AgentService $agentService;
  24. protected ProjectService $projectService;
  25. public function __construct(
  26. AgentService $agentService,
  27. ProjectService $projectService
  28. ) {
  29. $this->agentService = $agentService;
  30. $this->projectService = $projectService;
  31. }
  32. /**
  33. * 订单初始化
  34. */
  35. public function initialize($userId, $data)
  36. {
  37. $user = MemberUser::find($userId);
  38. if (! $user) {
  39. throw new Exception('用户不存在');
  40. }
  41. if ($user->state != 'enable') {
  42. throw new Exception('用户状态异常');
  43. }
  44. // 查询用户钱包
  45. $wallet = $user->wallet;
  46. // 查询默认地址
  47. $address = $user->address;
  48. $areaCode = $address ? $address->area_code : $data['area_code'];
  49. // 查询技师数据
  50. $coach = CoachUser::where('state', 'enable')
  51. ->whereHas('info', function ($query) {
  52. $query->where('state', 'approved');
  53. })
  54. ->whereHas('real', function ($query) {
  55. $query->where('state', 'approved');
  56. })
  57. ->whereHas('qual', function ($query) {
  58. $query->where('state', 'approved');
  59. })
  60. ->with(['info:id,nickname,avatar,gender'])
  61. ->find($data['coach_id']);
  62. if (! $coach) {
  63. throw new Exception('技师不存在');
  64. }
  65. // 查询技师排班
  66. // $schedule = CoachSchedule::where('coach_id', $coachId)
  67. // ->where('date', date('Y-m-d'))
  68. // ->first();
  69. // // 查询用户优惠券
  70. // $coupons = Coupon::where('user_id', $userId)
  71. // ->where('state', 'enable')
  72. // ->where('expire_time', '>', now())
  73. // ->get();
  74. // 获取项目详情
  75. $project = $this->projectService->getProjectDetail($data['project_id'], $areaCode);
  76. // 计算订单金额
  77. $amounts = $this->calculateOrderAmount($userId, $address?->id, $data['coach_id'], $data['project_id'], $project?->agent_id);
  78. return [
  79. 'wallet' => $wallet,
  80. 'coach' => $coach,
  81. 'project' => $project,
  82. 'address' => $address,
  83. // 'schedule' => $schedule,
  84. 'amounts' => $amounts,
  85. // 'coupons' => $coupons
  86. ];
  87. }
  88. /**
  89. * 创建订单
  90. */
  91. public function createOrder($userId, array $data)
  92. {
  93. try {
  94. return DB::transaction(function () use ($userId, $data) {
  95. // 1. 参数校验
  96. $user = MemberUser::where('id', $userId)
  97. ->where('state', 'enable')
  98. ->firstOrFail();
  99. $address = $user->addresses()
  100. ->where('id', $data['address_id'])
  101. ->firstOrFail();
  102. // 查询技师及其认证状态
  103. $coach = CoachUser::where('id', $data['coach_id'])
  104. ->where('state', 'enable')
  105. ->whereHas('info', function ($query) {
  106. $query->where('state', 'approved');
  107. })
  108. ->whereHas('qual', function ($query) {
  109. $query->where('state', 'approved');
  110. })
  111. ->whereHas('real', function ($query) {
  112. $query->where('state', 'approved');
  113. })
  114. ->firstOrFail();
  115. $project = Project::where('id', $data['project_id'])
  116. ->where('state', 'enable')
  117. ->firstOrFail();
  118. // 2. 创建订单
  119. $orderType = isset($data['order_id']) ? 'add_time' : 'normal';
  120. // 计算订单金额
  121. $amounts = $this->calculateOrderAmount(
  122. $userId,
  123. $data['address_id'],
  124. $data['coach_id'],
  125. $data['project_id'],
  126. $project->agent_id,
  127. $data['use_balance'] ?? false
  128. );
  129. $order = new Order;
  130. $order->user_id = $userId;
  131. $order->project_id = $data['project_id'];
  132. $order->coach_id = $data['coach_id'];
  133. $order->type = $orderType;
  134. $order->state = 'wait_pay';
  135. $order->source = 'platform';
  136. $order->total_amount = $amounts['total_amount'];
  137. $order->balance_amount = $amounts['balance_amount'];
  138. $order->pay_amount = $amounts['pay_amount'];
  139. $order->project_amount = $amounts['project_amount'];
  140. $order->traffic_amount = $orderType == 'add_time' ? 0 : $amounts['delivery_fee'];
  141. $order->payment_type = ($data['use_balance'] && $amounts['pay_amount'] == 0) ? 'balance' : null;
  142. $order->service_time = $data['service_time'];
  143. // 从用户地址获取位置信息
  144. $order->longitude = $address->longitude; // 经度
  145. $order->latitude = $address->latitude; // 纬度
  146. $order->location = $address->location; // 定位地址
  147. $order->address = $address->address; // 详细地址
  148. $order->area_code = $address->area_code; // 行政区划代码
  149. $order->save();
  150. // 3. 创建订单记录
  151. OrderRecord::create([
  152. 'order_id' => $order->id,
  153. 'object_id' => $userId,
  154. 'object_type' => MemberUser::class,
  155. 'state' => $orderType == 'add_time' ? 'add_time' : 'create',
  156. 'remark' => $orderType == 'add_time' ? '加钟订单' : '创建订单',
  157. ]);
  158. // 4. 余额支付处理
  159. if ($order->payment_type == 'balance') {
  160. $order->state = 'wait_receive';
  161. $order->save();
  162. // 创建订单支付记录
  163. OrderRecord::create([
  164. 'order_id' => $order->id,
  165. 'object_id' => $userId,
  166. 'object_type' => MemberUser::class,
  167. 'state' => 'pay',
  168. 'remark' => '余额支付',
  169. ]);
  170. // 扣除用户钱包总余额
  171. $user->wallet->decrement('total_balance', $order->balance_amount);
  172. // 扣除用户钱包可用余额
  173. $user->wallet->decrement('available_balance', $order->balance_amount);
  174. $user->wallet->save();
  175. // 创建技师排班
  176. // CoachSchedule::create([
  177. // 'coach_id' => $data['coach_id'],
  178. // 'date' => date('Y-m-d'),
  179. // 'state' => 'busy',
  180. // ]);
  181. // TODO: 发送抢单通知
  182. }
  183. return [
  184. 'order_id' => $order->id,
  185. 'payment_type' => $order->payment_type,
  186. ];
  187. });
  188. } catch (Exception $e) {
  189. Log::error('创建订单失败:', [
  190. 'message' => $e->getMessage(),
  191. 'user_id' => $userId,
  192. 'data' => $data,
  193. ]);
  194. throw $e;
  195. }
  196. }
  197. /**
  198. * 取消订单
  199. */
  200. public function cancelOrder($userId, $orderId)
  201. {
  202. return DB::transaction(function () use ($userId, $orderId) {
  203. try {
  204. $user = MemberUser::where('id', $userId)->firstOrFail();
  205. $order = $user->orders()->find($orderId);
  206. if (! $order) {
  207. throw new Exception('订单不存在');
  208. }
  209. // 判断订单状态
  210. if ($order->state == 'wait_receive') { // 已接单
  211. // 扣除20%费用
  212. $deductAmount = ($order->payment_amount + $order->balance_amount - $order->traffic_amount) * 0.2;
  213. $this->handleRefund($user, $order, $deductAmount, false);
  214. } elseif ($order->state == 'on_the_way') { // 已出发
  215. // 扣除50%费用并扣除路费
  216. $deductAmount = ($order->payment_amount + $order->balance_amount - $order->traffic_amount) * 0.5;
  217. $this->handleRefund($user, $order, $deductAmount, true);
  218. } elseif ($order->state == 'wait_pay') {
  219. // 待支付状态直接取消,无需退款
  220. } else {
  221. throw new Exception('当前订单状态不允许取消');
  222. }
  223. // 添加订单取消记录
  224. OrderRecord::create([
  225. 'order_id' => $orderId,
  226. 'object_id' => $userId,
  227. 'object_type' => MemberUser::class,
  228. 'state' => 'cancel',
  229. 'remark' => '用户取消订单',
  230. ]);
  231. // 修改订单状态
  232. $order->state = 'cancel';
  233. $order->save();
  234. return ['message' => '订单已取消'];
  235. } catch (Exception $e) {
  236. Log::error('取消订单失败:', [
  237. 'message' => $e->getMessage(),
  238. 'user_id' => $userId,
  239. 'order_id' => $orderId,
  240. ]);
  241. throw $e;
  242. }
  243. });
  244. }
  245. /**
  246. * 处理退款
  247. */
  248. private function handleRefund($user, $order, $deductAmount, $deductTrafficFee)
  249. {
  250. // 计算实际退款金额
  251. $refundAmount = $order->payment_amount + $order->balance_amount;
  252. if ($deductTrafficFee) {
  253. $refundAmount -= $order->traffic_amount;
  254. // 记录技师路费收入
  255. // ...
  256. }
  257. $refundAmount -= $deductAmount;
  258. // 优先从余额支付金额中扣除
  259. $balanceRefund = min($order->balance_amount, $refundAmount);
  260. if ($balanceRefund > 0) {
  261. // 添加钱包退款记录
  262. $refundRecord = $user->wallet->refundRecords()->create([
  263. 'refund_method' => 'balance',
  264. 'total_refund_amount' => $order->payment_amount + $order->balance_amount,
  265. 'actual_refund_amount' => '0.00',
  266. 'wallet_balance_refund_amount' => $balanceRefund,
  267. 'recharge_balance_refund_amount' => '0.00',
  268. 'remark' => '订单取消退还余额',
  269. 'order_id' => $order->id,
  270. ]);
  271. // 添加钱包交易记录
  272. $user->wallet->transRecords()->create([
  273. 'amount' => $balanceRefund,
  274. 'owner_type' => $refundRecord::class,
  275. 'owner_id' => $refundRecord->id,
  276. 'remark' => '订单取消退还余额',
  277. 'trans_type' => 'income',
  278. 'storage_type' => 'balance',
  279. 'amount' => $balanceRefund,
  280. 'before_balance' => $user->wallet->total_balance,
  281. 'after_balance' => $user->wallet->total_balance + $balanceRefund,
  282. 'before_recharge_balance' => '0.00',
  283. 'after_recharge_balance' => '0.00',
  284. 'trans_time' => now(),
  285. 'state' => 'success',
  286. ]);
  287. $user->wallet->increment('total_balance', $balanceRefund);
  288. $user->wallet->increment('available_balance', $balanceRefund);
  289. $user->wallet->save();
  290. }
  291. // 剩余退款金额从支付金额中退还
  292. $paymentRefund = $refundAmount - $balanceRefund;
  293. if ($paymentRefund > 0) {
  294. // 添加钱包退款记录
  295. $refundRecord = $user->wallet->refundRecords()->create([
  296. 'refund_method' => 'balance',
  297. 'total_refund_amount' => $order->payment_amount + $order->balance_amount,
  298. 'actual_refund_amount' => '0.00',
  299. 'wallet_balance_refund_amount' => $balanceRefund,
  300. 'recharge_balance_refund_amount' => '0.00',
  301. 'remark' => '订单取消退还余额',
  302. 'order_id' => $order->id,
  303. ]);
  304. // 添加钱包交易记录
  305. $user->wallet->transRecords()->create([
  306. 'amount' => $balanceRefund,
  307. 'owner_type' => $refundRecord::class,
  308. 'owner_id' => $refundRecord->id,
  309. 'remark' => '订单取消退还余额',
  310. 'trans_type' => 'income',
  311. 'storage_type' => 'balance',
  312. 'amount' => $balanceRefund,
  313. 'before_balance' => $user->wallet->total_balance,
  314. 'after_balance' => $user->wallet->total_balance + $balanceRefund,
  315. 'before_recharge_balance' => '0.00',
  316. 'after_recharge_balance' => '0.00',
  317. 'trans_time' => now(),
  318. 'state' => 'success',
  319. ]);
  320. $user->wallet->increment('total_balance', $paymentRefund);
  321. $user->wallet->increment('available_balance', $paymentRefund);
  322. $user->wallet->save();
  323. }
  324. // 记录平台收入
  325. if ($deductAmount > 0) {
  326. // TODO: 添加平台收入记录
  327. // PlatformIncome::create([...]);
  328. }
  329. }
  330. /**
  331. * 结束订单
  332. */
  333. public function finishOrder($userId, $orderId)
  334. {
  335. return DB::transaction(function () use ($userId, $orderId) {
  336. try {
  337. // 1. 参数校验
  338. $order = Order::where('user_id', $userId)
  339. ->where('id', $orderId)
  340. ->where('state', 'service_ing') // 订单状态必须是服务中
  341. ->firstOrFail();
  342. if (! $order) {
  343. throw new Exception('订单不能结束');
  344. }
  345. // 2. 创建订单历史记录
  346. OrderRecord::create([
  347. 'order_id' => $orderId,
  348. 'object_id' => $userId,
  349. 'object_type' => MemberUser::class,
  350. 'state' => 'finish',
  351. 'remark' => '服务完成',
  352. ]);
  353. // 3. 修改订单状态为服务结束
  354. $order->state = 'service_end';
  355. $order->save();
  356. return ['message' => '订单已完成'];
  357. } catch (Exception $e) {
  358. Log::error('结束订单失败:', [
  359. 'message' => $e->getMessage(),
  360. 'user_id' => $userId,
  361. 'order_id' => $orderId,
  362. ]);
  363. throw $e;
  364. }
  365. });
  366. }
  367. /**
  368. * 确认技师离开
  369. */
  370. public function confirmLeave($userId, $orderId)
  371. {
  372. return DB::transaction(function () use ($userId, $orderId) {
  373. try {
  374. // 1. 参数校验
  375. $order = Order::where('user_id', $userId)
  376. ->where('id', $orderId)
  377. ->where('state', 'service_end') // 订单状态必须是服务结束
  378. ->firstOrFail();
  379. if (! $order) {
  380. throw new Exception('订单不能撤离');
  381. }
  382. // 2. 添加订单撤离记录
  383. OrderRecord::create([
  384. 'order_id' => $orderId,
  385. 'object_id' => $userId,
  386. 'object_type' => MemberUser::class,
  387. 'state' => 'leave',
  388. 'remark' => '技师已离开',
  389. ]);
  390. // 3. 修改订单状态为撤离
  391. $order->state = 'leave';
  392. $order->save();
  393. return ['message' => '已确认技师离开'];
  394. } catch (Exception $e) {
  395. Log::error('确认技师离开失败:', [
  396. 'message' => $e->getMessage(),
  397. 'user_id' => $userId,
  398. 'order_id' => $orderId,
  399. ]);
  400. throw $e;
  401. }
  402. });
  403. }
  404. /**
  405. * 获取订单列表
  406. */
  407. public function getOrderList()
  408. {
  409. $userId = Auth::id();
  410. return Order::where('user_id', $userId)
  411. ->with([
  412. 'project:id,title,cover,price',
  413. 'coach:id,name,avatar',
  414. 'agent:id,company_name',
  415. 'address:id,address',
  416. ])
  417. ->orderBy('created_at', 'desc')
  418. ->paginate(10);
  419. }
  420. /**
  421. * 获取订单详情
  422. */
  423. public function getOrderDetail($orderId)
  424. {
  425. $userId = Auth::id();
  426. return Order::where('id', $orderId)
  427. ->where('user_id', $userId)
  428. ->with([
  429. 'project:id,title,cover,price,duration',
  430. 'coach:id,name,avatar,mobile',
  431. 'agent:id,company_name',
  432. 'address:id,address,latitude,longitude',
  433. 'records' => function ($query) {
  434. $query->orderBy('created_at', 'asc');
  435. },
  436. ])
  437. ->firstOrFail();
  438. }
  439. /**
  440. * 订单退款
  441. */
  442. public function refundOrder($orderId)
  443. {
  444. $userId = Auth::id();
  445. return DB::transaction(function () use ($orderId, $userId) {
  446. // 查询并锁定订单
  447. $order = Order::where('id', $orderId)
  448. ->where('user_id', $userId)
  449. ->where('state', 'pending')
  450. ->lockForUpdate()
  451. ->firstOrFail();
  452. // 更新订单状态
  453. $order->state = 'refunded';
  454. $order->save();
  455. // 添加订单记录
  456. OrderRecord::create([
  457. 'order_id' => $orderId,
  458. 'object_id' => $userId,
  459. 'object_type' => 'user',
  460. 'state' => 'refund',
  461. 'remark' => '订单退款',
  462. ]);
  463. // 创建退款记录
  464. WalletRefundRecord::create([
  465. 'order_id' => $orderId,
  466. 'user_id' => $userId,
  467. 'amount' => $order->total_amount,
  468. 'state' => 'success',
  469. ]);
  470. return ['message' => '退款成功'];
  471. });
  472. }
  473. /**
  474. * 获取代理商配置
  475. */
  476. public function getAgentConfig($agentId)
  477. {
  478. $agent = AgentInfo::where('id', $agentId)
  479. ->where('state', 'enable')
  480. ->firstOrFail();
  481. // $config = AgentConfig::where('agent_id', $agentId)->firstOrFail();
  482. return [
  483. // 'min_distance' => $config->min_distance,
  484. // 'min_fee' => $config->min_fee,
  485. // 'per_km_fee' => $config->per_km_fee
  486. ];
  487. }
  488. /**
  489. * 获取技师配置
  490. */
  491. public function getCoachConfig($coachId)
  492. {
  493. $coach = CoachUser::where('id', $coachId)
  494. ->where('state', 'enable')
  495. ->where('auth_state', 'passed')
  496. ->firstOrFail();
  497. // $config = CoachConfig::where('coach_id', $coachId)->firstOrFail();
  498. return [
  499. // 'delivery_fee_type' => $config->delivery_fee_type,
  500. // 'charge_delivery_fee' => $config->charge_delivery_fee
  501. ];
  502. }
  503. /**
  504. * 计算路费金额
  505. */
  506. public function calculateDeliveryFee($coachId, $projectId, $agentId, $distance)
  507. {
  508. // 查询技师数据
  509. $coach = CoachUser::where('state', 'enable')
  510. ->whereHas('info', function ($query) {
  511. $query->where('state', 'approved');
  512. })
  513. ->whereHas('real', function ($query) {
  514. $query->where('state', 'approved');
  515. })
  516. ->whereHas('qual', function ($query) {
  517. $query->where('state', 'approved');
  518. })
  519. ->find($coachId);
  520. if (! $coach) {
  521. throw new Exception('技师不存在');
  522. }
  523. // 查询技师项目
  524. $coachProject = $coach->projects()
  525. ->where('state', 'enable')
  526. ->where('project_id', $projectId)
  527. ->first();
  528. if (! $coachProject) {
  529. throw new Exception('项目不存在');
  530. }
  531. // 技师免收路费
  532. if ($coachProject->traffic_fee_type == 'free') {
  533. return 0;
  534. }
  535. // 查询代理商
  536. $agent = AgentInfo::where('state', 'enable')->find($agentId);
  537. if ($agent) {
  538. $agentProject = $agent->projects()
  539. ->where('state', 'enable')
  540. ->where('project_id', $projectId)
  541. ->first();
  542. if (! $agentProject) {
  543. throw new Exception('代理商项目不存在');
  544. }
  545. $config = $agent->projectConfig;
  546. } else {
  547. // 系统配置
  548. $config = SysConfig::where('key', 'delivery_fee')->firstOrFail();
  549. dd('暂停处理');
  550. }
  551. $fee = 0;
  552. if ($distance <= $config->min_distance) {
  553. $fee = $config->min_fee;
  554. } else {
  555. $extraDistance = $distance - $config->min_distance;
  556. $fee = $config->min_fee + ($extraDistance * $config->per_km_fee);
  557. }
  558. return $coachProject->delivery_fee_type == 'round_trip' ? $fee * 2 : $fee;
  559. }
  560. /**
  561. * 计算订单金额
  562. */
  563. public function calculateOrderAmount($userId, $addressId, $coachId, $projectId, $agentId, $useBalance = false)
  564. {
  565. // 参数校验
  566. $user = MemberUser::find($userId);
  567. if (! $user) {
  568. throw new Exception('用户不存在');
  569. }
  570. if ($user->state != 'enable') {
  571. throw new Exception('用户状态异常');
  572. }
  573. // 查询地址
  574. $address = $user->address()->find($addressId);
  575. // 查询技师数据
  576. $coach = CoachUser::where('state', 'enable')
  577. ->whereHas('info', function ($query) {
  578. $query->where('state', 'approved');
  579. })
  580. ->whereHas('real', function ($query) {
  581. $query->where('state', 'approved');
  582. })
  583. ->whereHas('qual', function ($query) {
  584. $query->where('state', 'approved');
  585. })
  586. ->with(['info:id,nickname,avatar,gender'])
  587. ->find($coachId);
  588. if (! $coach) {
  589. throw new Exception('技师不存在');
  590. }
  591. // 查询技师项目
  592. $coachProject = $coach->projects()
  593. ->where('state', 'enable')
  594. ->where('project_id', $projectId)
  595. ->first();
  596. if (! $coachProject) {
  597. throw new Exception('项目不存在');
  598. }
  599. // 查询项目
  600. $project = $coachProject->basicInfo;
  601. if (! $project) {
  602. throw new Exception('项目不存在');
  603. }
  604. if ($project->state != 'enable') {
  605. throw new Exception('项目状态异常');
  606. }
  607. // 查询代理商
  608. $agent = AgentInfo::where('state', 'enable')->find($agentId);
  609. if ($agent) {
  610. $agentProject = $agent->projects()
  611. ->where('state', 'enable')
  612. ->where('project_id', $projectId)
  613. ->first();
  614. if (! $agentProject) {
  615. throw new Exception('代理商项目不在');
  616. }
  617. $project->price = $agentProject->price;
  618. $project->duration = $agentProject->duration;
  619. $project->distance = $address->distance;
  620. }
  621. // 计算金额
  622. $projectAmount = $project->price;
  623. $deliveryFee = $this->calculateDeliveryFee($coachId, $projectId, $agentId, $address?->distance);
  624. // $tipAmount = request()->has('order_id') ? Order::find(request()->input('order_id'))->tip_amount : 0;
  625. $couponAmount = 0;
  626. if (request()->has('coupon_id')) {
  627. // $coupon = Coupon::where('id', request()->input('coupon_id'))
  628. // ->where('state', 'enable')
  629. // ->firstOrFail();
  630. // $couponAmount = $coupon->amount;
  631. }
  632. $totalAmount = $projectAmount + $deliveryFee - $couponAmount;
  633. $balanceAmount = 0;
  634. $payAmount = $totalAmount;
  635. if ($useBalance) {
  636. $wallet = $user->wallet;
  637. if ($wallet && $wallet->available_balance >= $totalAmount) {
  638. $balanceAmount = $totalAmount;
  639. $payAmount = 0;
  640. } elseif ($wallet) {
  641. $balanceAmount = $wallet->available_balance;
  642. $payAmount = $totalAmount - $balanceAmount;
  643. }
  644. }
  645. return [
  646. 'total_amount' => $totalAmount,
  647. 'balance_amount' => $balanceAmount,
  648. 'pay_amount' => $payAmount,
  649. 'coupon_amount' => $couponAmount,
  650. // 'tip_amount' => $tipAmount,
  651. 'project_amount' => $projectAmount,
  652. 'delivery_fee' => $deliveryFee,
  653. ];
  654. }
  655. /**
  656. * 加钟
  657. */
  658. public function addTime($userId, $orderId)
  659. {
  660. $order = Order::where('id', $orderId)
  661. ->where('user_id', $userId)
  662. ->firstOrFail();
  663. return $this->createOrder($userId, $order->project_id, $order->address_id, $order->coach_id, 0, $orderId);
  664. }
  665. /**
  666. * 指定技师
  667. */
  668. public function assignCoach($userId, $orderId, $coachId)
  669. {
  670. return DB::transaction(function () use ($userId, $orderId, $coachId) {
  671. // 参数校验
  672. $user = MemberUser::where('id', $userId)
  673. ->where('state', 'enable')
  674. ->firstOrFail();
  675. $order = Order::where('id', $orderId)
  676. ->where('user_id', $userId)
  677. ->whereIn('state', [0, 1, 6])
  678. ->firstOrFail();
  679. $coach = CoachUser::where('id', $coachId)
  680. ->where('state', 'enable')
  681. ->where('auth_state', 'passed')
  682. ->firstOrFail();
  683. // $schedule = CoachSchedule::where('coach_id', $coachId)
  684. // ->where('date', date('Y-m-d'))
  685. // ->where('state', 'free')
  686. // ->firstOrFail();
  687. // 修改订单
  688. $order->coach_id = $coachId;
  689. if ($order->state == 'created') {
  690. $amounts = $this->calculateOrderAmount($userId, $order->address_id, $coachId, $order->project_id, $order->agent_id, $order->payment_type == 'balance');
  691. $order->total_amount = $amounts['total_amount'];
  692. $order->balance_amount = $amounts['balance_amount'];
  693. $order->pay_amount = $amounts['pay_amount'];
  694. $order->coupon_amount = $amounts['coupon_amount'];
  695. // $order->tip_amount = $amounts['tip_amount'];
  696. $order->project_amount = $amounts['project_amount'];
  697. $order->delivery_fee = $amounts['delivery_fee'];
  698. if ($order->payment_type == 'balance') {
  699. $order->state = 'paid';
  700. }
  701. }
  702. if ($order->state == 'paid') {
  703. $order->state = 'assigned';
  704. }
  705. $order->save();
  706. // 创建订单历史
  707. OrderRecord::create([
  708. 'order_id' => $order->id,
  709. 'type' => 'assigned',
  710. 'user_id' => $userId,
  711. 'coach_id' => $coachId,
  712. ]);
  713. OrderRecord::create([
  714. 'order_id' => $order->id,
  715. 'type' => 'accepted',
  716. 'user_id' => $userId,
  717. 'coach_id' => $coachId,
  718. 'remark' => '抢单成功',
  719. ]);
  720. // 更新抢单池
  721. OrderGrabRecord::where('order_id', $orderId)
  722. ->update(['state' => 'success', 'coach_id' => $coachId]);
  723. // 更新排班
  724. // $schedule->state = 'busy';
  725. // $schedule->save();
  726. return true;
  727. });
  728. }
  729. }