IndexService.php 10 KB

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