OrderController.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. <?php
  2. namespace App\Http\Controllers\Api;
  3. use App\Http\Controllers\ApiController;
  4. use App\Models\MemberOpenId;
  5. use App\Models\Order;
  6. use App\Models\OrderItem;
  7. use App\Models\TableNumber;
  8. use App\Servers\CommonServer;
  9. use App\Servers\OrderServer;
  10. use App\Servers\RedisDataServer;
  11. use App\Servers\ShoppingCartServer;
  12. use App\Servers\ShopServer;
  13. use App\Servers\WeixinServer;
  14. use Carbon\Carbon;
  15. use Illuminate\Validation\Rules\In;
  16. /**
  17. * 外卖订单
  18. */
  19. class OrderController extends ApiController
  20. {
  21. /**
  22. * 前端获取订单状态
  23. */
  24. function getOrderStatus()
  25. {
  26. $statusArr = [
  27. 0=>'全部',
  28. 1=>'待支付',
  29. 2=>'制作中',
  30. 3=>'已完成',
  31. 4=>'已取消',
  32. 5=>'退款',
  33. ];
  34. $data = [];
  35. foreach ($statusArr as $key=>$value){
  36. $data[] = [
  37. 'key' => $key,
  38. 'name' => $value,
  39. ];
  40. }
  41. return $this->apiResponseSuccess('成功',array_values($data));
  42. }
  43. /**
  44. * 下单
  45. */
  46. function createOrder()
  47. {
  48. $m_id = $this->getMemberId();//用户id
  49. $commonServer = CommonServer::creatServer();
  50. $shop_id = $commonServer->filtrationStr('shop_id');//商家id
  51. $order_type = $commonServer->filtrationStr('order_type',1);//订单类型 1堂食订单 2打包订单
  52. $table_number = $commonServer->filtrationStr('table_number');//桌号
  53. $diner_number = $commonServer->filtrationStr('diner_number');//就餐人数
  54. $note = $commonServer->filtrationStr('note');//备注
  55. $reserve_time = $commonServer->filtrationStr('reserve_time');//预约时间
  56. if (empty($shop_id)) return $this->apiResponseError('商家错误');
  57. if (!in_array($order_type,[1,2])){
  58. return $this->apiResponseError('就餐方式错误');
  59. }
  60. if (empty($table_number) || $table_number < 0) return $this->apiResponseError('桌号错误');
  61. if (empty($diner_number) || $diner_number < 0) return $this->apiResponseError('就餐人数错误');
  62. if ($table_number > 1000) return $this->apiResponseError('桌号最大1000');
  63. if ($diner_number > 0) return $this->apiResponseError('就餐人数最大1000');
  64. if (!empty($note) && mb_strlen($note) > 50 ) return $this->apiResponseError('备注最大50');
  65. if(!empty($reserve_time)){
  66. // 将预约时间转换为时间戳
  67. $reserve_timestamp = strtotime($reserve_time);
  68. // 获取当前时间
  69. $current_time = time();
  70. // 计算20分钟后的时间
  71. $time_plus_20min = $current_time + (20 * 60);
  72. // 获取今天的日期(Y-m-d格式)
  73. $today_date = date('Y-m-d');
  74. // 获取预约时间的日期部分
  75. $reserve_date = date('Y-m-d', $reserve_timestamp);
  76. // 判断预约时间是否是今天且比当前时间大20分钟
  77. if ($reserve_date === $today_date && $reserve_timestamp >= $time_plus_20min) {
  78. // 检查预约时间是否不超过今天结束时间
  79. $end_of_today = strtotime(date('Y-m-d 23:59:59'));
  80. if ($reserve_timestamp >= $end_of_today) {
  81. return $this->apiResponseError('预约时间不正确');
  82. }
  83. } elseif($reserve_date !== $today_date) {
  84. return $this->apiResponseError('预约时间不超过今天');
  85. }
  86. $is_reserve = 1;
  87. }else{
  88. $is_reserve = 0;
  89. }
  90. //获取商家信息
  91. $shop = ShopServer::creatServer()->getShopInfo($shop_id);
  92. if (empty($shop)) return $this->apiResponseError('该商家不存在');
  93. if ($shop['status'] != 1) return $this->apiResponseError('商家闭店休息中');
  94. //获取购买的商品信息
  95. $goods = ShoppingCartServer::creatServer()->getShoppingList($m_id,$shop_id);
  96. if (count($goods['goods_list']) <= 0) {
  97. return $this->apiResponseError('商品信息错误');
  98. }
  99. //加锁
  100. $lock_key = $shop_id.'lockOrderCreate';
  101. $lock_value = uniqid(bin2hex(random_bytes(10)), true);
  102. $lock = RedisDataServer::creatServer()->lockKey($lock_key,$lock_value,500);
  103. if (!$lock){
  104. return $this->apiResponseError('下单人数过多,请稍候');
  105. }
  106. //下单
  107. $res = OrderServer::creatServer()->createOrder($m_id,$shop_id,$order_type,$table_number,$diner_number,$is_reserve,$reserve_time,$note,$goods);
  108. //删除锁key-防止死锁
  109. RedisDataServer::creatServer()->unLockKey($lock_key,$lock_value);
  110. if ($res['code'] == 0) {
  111. return $this->apiResponseError($res['msg']);
  112. }
  113. return $this->apiResponseSuccess('订单创建成功', $res['data']);
  114. }
  115. /**
  116. * 下单
  117. */
  118. function createV2Order()
  119. {
  120. $m_id = $this->getMemberId();//用户id
  121. $commonServer = CommonServer::creatServer();
  122. $shop_id = $commonServer->filtrationStr('shop_id');//商家id
  123. $order_type = $commonServer->filtrationStr('order_type',1);//订单类型 1堂食订单 2打包订单
  124. $table_number = $commonServer->filtrationStr('table_number');//桌号
  125. $diner_number = $commonServer->filtrationStr('diner_number');//就餐人数
  126. $note = $commonServer->filtrationStr('note');//备注
  127. $shopping_cart = request()->input('shopping_cart',[]);//商品规格数组
  128. $reserve_time = $commonServer->filtrationStr('reserve_time');//预约时间
  129. if (empty($shop_id)) return $this->apiResponseError('商家错误');
  130. if (!in_array($order_type,[1,2])){
  131. return $this->apiResponseError('就餐方式错误');
  132. }
  133. if (empty($table_number) || $table_number < 0) return $this->apiResponseError('桌号错误');
  134. if (empty($diner_number) || $diner_number < 0) return $this->apiResponseError('就餐人数错误');
  135. if (empty($shopping_cart)) return $this->apiResponseError('请添加购物车');
  136. if ($table_number > 1000) return $this->apiResponseError('桌号最大1000');
  137. if ($diner_number > 1000) return $this->apiResponseError('就餐人数最大1000');
  138. if (!empty($note) && mb_strlen($note) > 50 ) return $this->apiResponseError('备注最大50');
  139. if(!empty($reserve_time)){
  140. // 将预约时间转换为时间戳
  141. $reserve_timestamp = strtotime($reserve_time);
  142. // 获取当前时间
  143. $current_time = time();
  144. // 计算20分钟后的时间
  145. $time_plus_20min = $current_time + (20 * 60);
  146. // 获取今天的日期(Y-m-d格式)
  147. $today_date = date('Y-m-d');
  148. // 获取预约时间的日期部分
  149. $reserve_date = date('Y-m-d', $reserve_timestamp);
  150. // 判断预约时间是否是今天且比当前时间大20分钟
  151. if ($reserve_date === $today_date && $reserve_timestamp >= $time_plus_20min) {
  152. // 检查预约时间是否不超过今天结束时间
  153. $end_of_today = strtotime(date('Y-m-d 23:59:59'));
  154. if ($reserve_timestamp >= $end_of_today) {
  155. return $this->apiResponseError('预约时间不正确');
  156. }
  157. } elseif($reserve_date !== $today_date) {
  158. return $this->apiResponseError('预约时间不超过今天');
  159. }
  160. $is_reserve = 1;
  161. $reserve_time = date('Y-m-d H:i:s', $reserve_timestamp);
  162. }else{
  163. $is_reserve = 0;
  164. $reserve_time = date('Y-m-d H:i:s');
  165. }
  166. //获取商家信息
  167. $shop = ShopServer::creatServer()->getShopInfo($shop_id);
  168. if (empty($shop)) return $this->apiResponseError('该商家不存在');
  169. if ($shop['status'] != 1) return $this->apiResponseError('商家闭店休息中');
  170. //获取桌号信息
  171. $table = TableNumber::where('shop_id',$shop_id)->where('number',$table_number)->select(['id','status'])->first();
  172. if (empty($table)) return $this->apiResponseError('桌号不存在');
  173. if ($table->{'status'} != 1) return $this->apiResponseError('桌号不可用');
  174. //获取购买的商品信息
  175. $cartResult = ShoppingCartServer::creatServer()->getCartList($shopping_cart);
  176. if ($cartResult['code'] == 0) {
  177. return $this->apiResponseError($cartResult['msg']);
  178. }
  179. $goods = $cartResult['data'];
  180. //加锁
  181. $lock_key = $shop_id.'lockOrderCreate';
  182. $lock_value = uniqid(bin2hex(random_bytes(10)), true);
  183. $lock = RedisDataServer::creatServer()->lockKey($lock_key,$lock_value,500);
  184. if (!$lock){
  185. return $this->apiResponseError('下单人数过多,请稍候');
  186. }
  187. //下单
  188. $res = OrderServer::creatServer()->createOrder($m_id,$shop_id,$order_type,$table_number,$diner_number,$is_reserve,$reserve_time,$note,$goods,$shopping_cart);
  189. //删除锁key-防止死锁
  190. RedisDataServer::creatServer()->unLockKey($lock_key,$lock_value);
  191. if ($res['code'] == 0) {
  192. return $this->apiResponseError($res['msg']);
  193. }
  194. return $this->apiResponseSuccess('订单创建成功', $res['data']);
  195. }
  196. /**
  197. * 支付订单
  198. */
  199. function payOrder()
  200. {
  201. $m_id = $this->getMemberId();//用户id
  202. $commonServer = CommonServer::creatServer();
  203. $order_id = $commonServer->filtrationStr('order_id');//订单id
  204. $pay_type = $commonServer->filtrationStr('pay_type',1);//支付方式 1微信 2支付宝
  205. if (empty($order_id)) return $this->apiResponseError('请选择订单');
  206. if (!in_array($pay_type, [1, 2, 3])) return $this->apiResponseError('支付方式错误');
  207. $order_info = Order::where('id', $order_id)
  208. ->where('m_id', $m_id)
  209. ->where('order_status', 1)
  210. ->select(['id', 'order_status','order_money', 'pay_money', 'order_sn', 'm_id','shop_id'])
  211. ->first();
  212. if (empty($order_info)) {
  213. return $this->apiResponseError('订单已失效');
  214. }
  215. //获取商家信息
  216. $shop = ShopServer::creatServer()->getShopInfo($order_info->{'shop_id'});
  217. if (empty($shop)) return $this->apiResponseError('该商家不存在');
  218. if ($shop['status'] != 1) return $this->apiResponseError('商家已闭店');
  219. //定义返回参数
  220. $data = ['pay_status' => false, 'wx_pay' => [], 'zfb_pay' => []];
  221. if($pay_type == 1) {
  222. //微信支付
  223. $notify_url = route('notify.order_wx');
  224. $wx_openid = MemberOpenId::where('m_id', $m_id)->where('type', 4)->value('openid');
  225. if (empty($wx_openid)) {
  226. return $this->apiResponseError('用户信息错误');
  227. }
  228. $wx_pay = WeixinServer::creatServer()->wxJsPay($order_info->{'order_sn'}, $order_info->{'pay_money'}, $notify_url, '订单', $wx_openid);
  229. $data['wx_pay'] = $wx_pay;
  230. }elseif ($pay_type == 2) {
  231. $data['zfb_pay'] = [];
  232. }
  233. return $this->apiResponseSuccess('成功', $data);
  234. }
  235. /**
  236. * 用户获取外卖订单列表
  237. */
  238. function getOrderList()
  239. {
  240. $m_id = $this->getMemberId();//用户id
  241. $commonServer = CommonServer::creatServer();
  242. $status = $commonServer->filtrationStr('status',-1);//状态 0全部1=>'待支付',2=>'制作中',3=>'已完成',4=>'已取消',5=>'退款',
  243. $shop_id = $commonServer->filtrationStr('shop_id');//商家id
  244. if (empty($shop_id)) return $this->apiResponseError('商家错误');
  245. $where = [['m_id',$m_id], ['is_del',0], ['shop_id',$shop_id]];
  246. $list = Order::where($where)
  247. ->where(function ($q) use ($status){
  248. if (in_array($status,[1,2,3,4,5])){
  249. $q->where('order_status',$status);
  250. }
  251. })
  252. ->select(['id','order_sn','order_type','order_status','pay_money','goods_number','created_at','shop_id','note','shopping_cart','is_reserve','reserve_time'])
  253. ->orderBy('id','desc')
  254. ->paginate(10);
  255. foreach ($list as $value){
  256. $shop_info = ShopServer::creatServer()->getShopInfo($value->{'shop_id'});
  257. $value->{'shop_name'} = $commonServer->truncateChineseString($shop_info['shop_name'],16);
  258. $value->{'item'} = OrderItem::from('order_item as o')
  259. ->leftJoin('goods as g', 'o.goods_id', '=', 'g.id')
  260. ->where('o.order_id',$value->{'id'})
  261. ->select(['o.id','o.goods_id','o.goods_name','o.goods_img','o.goods_number','g.status'])
  262. ->orderBy('o.id','asc')
  263. ->get();
  264. $value->initializeModel();
  265. }
  266. return $this->apiResponseSuccess('成功', [
  267. 'items' => $list->items(),
  268. 'total' => $list->total(),
  269. 'limit' => 10,
  270. ]);
  271. }
  272. /**
  273. * 取消订单
  274. */
  275. function cancelOrder()
  276. {
  277. $m_id = $this->getMemberId();//用户id
  278. $commonServer = CommonServer::creatServer();
  279. $order_id = $commonServer->filtrationStr('order_id');//订单id
  280. if (empty($order_id) || !is_numeric($order_id)) {
  281. return $this->apiResponseError('请选择订单');
  282. }
  283. $order_info = Order::where('m_id', $m_id)
  284. ->where('id', $order_id)
  285. ->where('is_del',0)
  286. ->select(['id','order_sn','m_id', 'order_type','order_status','shop_id'])
  287. ->first();
  288. if (empty($order_info)) return $this->apiResponseError('订单信息错误');
  289. if ($order_info->{'order_status'} != 1) {
  290. return $this->apiResponseError('当前订单不能取消');
  291. }
  292. $res = Order::where('id', $order_info->{'id'})->update(['order_status' => 4]);
  293. if (!$res){
  294. return $this->apiResponseError('操作失败');
  295. }
  296. return $this->apiResponseSuccess('操作成功');
  297. }
  298. /**
  299. * 订单详情
  300. */
  301. function getOrderInfo()
  302. {
  303. $m_id = $this->getMemberId();//用户id
  304. $commonServer = CommonServer::creatServer();
  305. $order_id = $commonServer->filtrationStr('order_id');//订单id
  306. if (empty($order_id)) return $this->apiResponseError('请选择订单');
  307. $where = [['m_id',$m_id], ['is_del',0], ['id',$order_id]];
  308. $order = Order::where($where)
  309. ->select(['id','order_sn','order_type','pay_type','m_id','note','order_status','pay_money','goods_number','shop_id','created_at','pack_price','table_number','diner_number','number','note','shopping_cart','is_reserve','reserve_time'])
  310. ->first();
  311. if (empty($order)) return $this->apiResponseError('订单不存在');
  312. if ($order->{'order_type'} == 1) {//堂食打包费为0
  313. $order->{'pack_price'} = 0;
  314. }
  315. $order->{'shop'} = ShopServer::creatServer()->getShopInfo($order->{'shop_id'});
  316. $order->{'item'} = OrderItem::from('order_item as o')
  317. ->leftJoin('goods as g', 'o.goods_id', '=', 'g.id')
  318. ->where('o.order_id',$order_id)
  319. ->select(['o.id','o.goods_id','o.goods_name','o.goods_img','o.goods_attr','o.goods_number','o.goods_price','o.goods_money','o.goods_spec_list','g.status'])
  320. ->orderBy('o.id','asc')
  321. ->get();
  322. $order->initializeModel();
  323. return $this->apiResponseSuccess('成功', $order);
  324. }
  325. }