FinanceService.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <?php
  2. /**
  3. * @Name
  4. * @Description
  5. * @Author 刘学玺
  6. * @Date 2023/11/23 20:57
  7. */
  8. namespace App\Http\Services\Admin;
  9. use App\Exceptions\ApiException;
  10. use App\Http\Services\BaseService;
  11. use App\Models\Admin;
  12. use App\Models\Artificer;
  13. use App\Models\ArtificerSite;
  14. use App\Models\Order;
  15. use App\Models\OrderGrab;
  16. use App\Models\ProjectRelevancy;
  17. use App\Models\User;
  18. use App\Models\UserWithdraw;
  19. use App\Models\UserWithdrawLog;
  20. use Exception;
  21. use Illuminate\Support\Facades\Auth;
  22. use Illuminate\Support\Facades\DB;
  23. class FinanceService extends BaseService
  24. {
  25. private $message = [
  26. 'no_data' => '当前订单不存在!',
  27. 'delete_success' => '删除成功',
  28. 'delete_fail' => '删除失败!',
  29. 'reset_success' => '重置成功',
  30. 'reset_fail' => '重置失败!',
  31. 'over_success' => '结束成功',
  32. 'over_fail' => '结束失败!',
  33. 'audit_success' => '审核操作成功',
  34. 'audit_fail' => '审核操作失败!'
  35. ];
  36. /**
  37. * 提现管理
  38. * Method : Interface withdraw
  39. * @param array $data
  40. * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Foundation\Application|\Illuminate\Http\Response
  41. */
  42. public function withdraw(array $data)
  43. {
  44. $model = $this->queryCondition(UserWithdraw::query(), $data, 'order_sn');
  45. if (!empty($data['member'])) {
  46. $where = [
  47. ['user_nickname', 'like', '%' . $data['member'] . '%', 'or'],
  48. ['mobile', 'like', '%' . $data['member'] . '%', 'or']
  49. ];
  50. $ids = User::where($where)->pluck('id');
  51. $model->whereIn('user_id', $ids);
  52. }
  53. if (!empty($data['payee'])) {
  54. $where = [
  55. ['zfb_name', 'like', '%' . $data['payee'] . '%', 'or'],
  56. ['zfb_action', 'like', '%' . $data['payee'] . '%', 'or']
  57. ];
  58. $model->where($where);
  59. }
  60. // $model->with(['project', 'user', 'artificer']);
  61. $list = $model
  62. // ->select('id', 'order_sn', 'price', 'project_id', 'type', 'user_id', 'create_time', 'pay_time', 'return_time', 'appoint_time', 'voucher_price', 'balance_price', 'pay_price', 'pay_type', 'tax_price', 'status', 'jiedan_js_id', 'jiedan_time', 'start_time', 'finish_time', 'province', 'city', 'district', 'address', 'lng', 'lat')
  63. // ->orderBy('id', 'desc')
  64. ->with(['user', 'user.artificer', 'user.distributor', 'admin'])
  65. ->latest('create_time')
  66. ->paginate($data['pageSize'])
  67. ->toArray();
  68. return $this->apiSuccess('', [
  69. 'list' => $list['data'],
  70. 'total' => $list['total']
  71. ]);
  72. }
  73. public function audit(array $data)
  74. {
  75. $status = $data['status'];
  76. $id = $data['id'];
  77. $admin = Auth::user();
  78. DB::beginTransaction();
  79. try {
  80. if ($status == 2) {
  81. $withdraw = UserWithdraw::where('id', $id)->lockForUpdate()->first();
  82. !$withdraw && $this->apiError($this->message['audit_fail']);
  83. $withdraw->status && $this->apiError($this->message['audit_fail']);
  84. $user = User::where('id', $withdraw->user_id)->lockForUpdate()->first();
  85. !$user && $this->apiError($this->message['audit_fail']);
  86. $user->where('id', $withdraw->user_id)->increment('balance', $withdraw->money);
  87. $withdraw_data['status'] = $status;
  88. $withdraw_data['chuli_time'] = time();
  89. $withdraw_data['admin_id'] = $admin['id'];
  90. $this->commonUpdate(UserWithdraw::query(), $withdraw->id, $withdraw_data, '', $this->message['audit_fail'], false);
  91. $withdraw_log_data['user_id'] = $withdraw->user_id;
  92. $withdraw_log_data['money'] = $withdraw->money;
  93. $withdraw_log_data['type'] = 100;
  94. $withdraw_log_data['remark'] = '提现拒绝,余额返还';
  95. $withdraw_log_data['add_time'] = time();
  96. $withdraw_log_data['obj_id'] = intval($id);
  97. $withdraw_log_data['yue'] = sprintf("%01.2f",floatval($user->balance) + floatval($withdraw->money));
  98. $response = $this->commonCreate(UserWithdrawLog::query(), $withdraw_log_data, $this->message['audit_success'], $this->message['audit_fail'], false);
  99. }
  100. DB::commit();
  101. } catch (ApiException $e) {
  102. DB::rollback();
  103. $this->apiError($e->getMessage(), $e->getCode());
  104. } catch (Exception $e) {
  105. DB::rollback();
  106. throw $e;
  107. }
  108. return $response;
  109. }
  110. public function withdrawLog(array $data)
  111. {
  112. $model = $this->queryCondition(UserWithdrawLog::query(), $data,);
  113. // if (!empty($data['key'])) {
  114. // $where = [
  115. // ['id', 'like', '%' . $data['key'] . '%'],
  116. // ['user_nickname', 'like', '%' . $data['key'] . '%', 'or'],
  117. // ['mobile', 'like', '%' . $data['key'] . '%', 'or']
  118. // ];
  119. // $ids = User::where($where)->pluck('id');
  120. // $model->whereIn('user_id', $ids);
  121. // }
  122. $list = $model
  123. // ->with(['user','user.artificer','user.distributor','admin'])
  124. ->with(['user.artificer', 'withdraw.admin', 'order', 'order.project', 'order.user'])
  125. ->where('user_id', $data['user_id'])
  126. ->latest('add_time')
  127. ->paginate($data['pageSize'])
  128. ->toArray();
  129. return $this->apiSuccess('', [
  130. 'list' => $list['data'],
  131. 'total' => $list['total']
  132. ]);
  133. }
  134. /**
  135. * 重置接单技师
  136. * Method : Interface reset
  137. * @param array $data
  138. * @throws \App\Exceptions\ApiException
  139. */
  140. public function reset(array $data)
  141. {
  142. DB::beginTransaction();
  143. try {
  144. $order_id = $data['id'];
  145. $order = Order::where('id', $order_id)->lockForUpdate()->first();
  146. !$order && $this->apiError($this->message['no_data']);
  147. !in_array($order->status, [1, 2]) && $this->apiError($this->message['reset_fail']);
  148. $artificer_id = $order->jiedan_js_id;
  149. // 存在指派技师
  150. if ($artificer_id) {
  151. $grab = OrderGrab::where(['order_id' => $order_id, 'js_id' => $artificer_id])->lockForUpdate()->first();
  152. if ($grab) {
  153. // 重置抢单表状态
  154. $grab_data['status'] = 0;
  155. $this->commonUpdate(OrderGrab::query(), $grab->id, $grab_data, '', $this->message['reset_fail'], false);
  156. }
  157. }
  158. // 重置接单技师
  159. $order_data['jiedan_js_id'] = 0;
  160. $response = $this->commonUpdate(Order::query(), $order_id, $order_data, $this->message['reset_success'], $this->message['reset_fail'], false);
  161. DB::commit();
  162. } catch (ApiException $e) {
  163. DB::rollback();
  164. $this->apiError($e->getMessage(), $e->getCode());
  165. } catch (Exception $e) {
  166. DB::rollback();
  167. throw $e;
  168. }
  169. return $response;
  170. }
  171. public function delete(array $data)
  172. {
  173. $delete_id = $data['id'];
  174. $order = Order::find($delete_id);
  175. !$order && $this->apiError($this->message['no_data']);
  176. $order->status && $this->apiError($this->message['delete_fail']);
  177. return $this->commonIsDelete(Order::query(), [$delete_id], $this->message['delete_success'], $this->message['delete_fail']);
  178. }
  179. public function over(array $data)
  180. {
  181. DB::beginTransaction();
  182. try {
  183. $order_id = $data['id'];
  184. $order = Order::where('id', $order_id)->lockForUpdate()->first();
  185. !in_array($order->status, [2, 6]) && $this->apiError($this->message['over_fail']);
  186. $data = [
  187. 'status' => 3,
  188. 'finish_time' => time()
  189. ];
  190. $response = $this->commonUpdate(Order::query(), $order_id, $data, $this->message['over_success'], $this->message['over_fail']);
  191. DB::commit();
  192. } catch (ApiException $e) {
  193. DB::rollback();
  194. $this->apiError($e->getMessage(), $e->getCode());
  195. } catch (Exception $e) {
  196. DB::rollback();
  197. throw $e;
  198. }
  199. return $response;
  200. }
  201. public function grab(array $data)
  202. {
  203. $order_id = $data['id'];
  204. $order = Order::find($order_id)->toArray();
  205. $list = OrderGrab::with('artificer.site')->where('order_id', $order_id)->oldest('create_time')->get()->toArray();
  206. foreach ($list as &$item) {
  207. if ($item['artificer']['site'])
  208. $item['distance'] = get_distance([$order['lng'], $order['lat']], [$item['artificer']['site']['lng'], $item['artificer']['site']['lat']]);
  209. }
  210. return $this->apiSuccess('', ['list' => $list]);
  211. }
  212. public function vicinity(array $data)
  213. {
  214. $code = 156370600;
  215. $order_id = $data['id'];
  216. $page = $data['page'];
  217. $pageSize = $data['pageSize'];
  218. $range_artificer_ids = [];
  219. // 第一步 按照城市编码获取技师定位数据
  220. $order = Order::find($order_id);
  221. $site = ArtificerSite::with('time')->where('city_code', $code)->select('js_id', 'lng', 'lat')->get()->toArray();
  222. $week = date('w', time());
  223. $date = date('H:i');
  224. foreach ($site as $item) {
  225. $distance = get_distance([$order->lng, $order->lat], [$item['lng'], $item['lat']]);
  226. $status = 0;
  227. if ($distance <= 60 && !in_array($item['js_id'], $range_artificer_ids)) {
  228. if ($item['time'] && $item['time']['times'] && in_array($week, json_decode($item['time']['weeks']))) {
  229. // 开关类型
  230. $status = 1;
  231. // 时间段类型
  232. // foreach ($item['time']['times'] as $vo){
  233. // if(strtotime($date) >= strtotime($vo['js_start_time']) && strtotime($date) <= strtotime($vo['js_end_time'])){
  234. // $status = 1;
  235. // break;
  236. // }
  237. // }
  238. }
  239. $status && array_push($range_artificer_ids, $item['js_id']);
  240. }
  241. }
  242. // $artificer_ids = array_column($site,'js_id');
  243. // 第二步 筛选开通项目技师
  244. $auth_artificer_ids = ProjectRelevancy::whereIn('js_id', $range_artificer_ids)->where('project_id', $order->project_id)->where('status', '1')->pluck('js_id')->toArray();
  245. $list = Artificer::with('site')->whereIn('id', $auth_artificer_ids)->where('js_status', '1')->get()->toArray();
  246. // 第三步 循环排序距离
  247. foreach ($list as &$item) {
  248. $item['distance'] = get_distance([$order->lng, $order->lat], [$item['site']['lng'], $item['site']['lat']]);
  249. }
  250. // 根据列进行排序
  251. $distances = array_column($list, 'distance');
  252. array_multisort($distances, SORT_ASC, $list);
  253. // 第四步 分页
  254. $offset = ($page - 1) * $pageSize; // 开始截取的索引
  255. $result = array_slice($list, $offset, $pageSize);
  256. return $this->apiSuccess('', ['list' => $list, 'total' => count($list)]);
  257. }
  258. }