Order.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. <?php
  2. namespace app\api\controller;
  3. use think\Db;
  4. use EasyWeChat\Factory;
  5. /**
  6. * @title 会员订单管理
  7. * @controller Order
  8. * @group base
  9. */
  10. class Order extends Base
  11. {
  12. public function initialize()
  13. {
  14. parent::check_login();
  15. }
  16. /**
  17. * @title 生成订单(立即购买)
  18. * @desc 生成订单(立即购买)
  19. * @author qc
  20. * @url /api/Order/createOrderByImmediately
  21. * @method POST
  22. * @header name:Authorization require:1 desc:Token
  23. * @param name:goods_id type:int require:1 default:-- desc:商品id
  24. * @param name:goods_no type:int require:1 default:-- desc:商品货号
  25. * @param name:price_total type:float require:1 default:-- desc:支付金额(优惠后的商品金额+运费)
  26. * @param name:num type:int require:1 default:1 desc:商品数量
  27. * @param name:price_goods type:float require:0 default:0 desc:商品总金额(没优惠的)
  28. * @param name:price_express type:float require:0 default:0 desc:运费
  29. * @param name:add_id type:int require:1 default:0 desc:收货地址id
  30. * @param name:remark type:string require:0 default:0 desc:订单备注
  31. * @param name:source type:int require:0 default:0 desc:商城的为0(默认),积分商城的值为1
  32. * @param name:integral type:int require:0 default:0 desc:使用多少积分,source为1时必传
  33. * @param name:int_cash type:float require:0 default:0 desc:积分抵扣多少钱,source为1时必传
  34. * @param name:cl_id type:int require:0 default:0 desc:会员优惠券id,使用优惠券必传
  35. * @param name:coupon_cash type:float require:0 default:0 desc:会员优惠券抵扣金额
  36. * @return name:order_id type:int require:0 default:0 desc:成功时返回订单id
  37. */
  38. public function createOrderByImmediately()
  39. {
  40. $goods_id = input("post.goods_id");
  41. $goods_no = input("post.goods_no");
  42. $price_total = input("post.price_total");
  43. $price_goods = input("post.price_goods");
  44. $price_express = input("post.price_express");
  45. $num = input("post.num",1);
  46. $add_id = input("post.add_id");
  47. $source = input("post.source",0);
  48. $integral = input("post.integral",0);
  49. $int_cash = input("post.int_cash",0);
  50. $cl_id = input("post.cl_id",0);
  51. $coupon_cash = input("post.coupon_cash",0);
  52. $remark = input("post.remark",0);
  53. //商品验证start
  54. $goods_info = Db::table('store_goods')->field('id,spec,stock,is_integral')
  55. ->where(['id'=>$goods_id,'status'=>1,'is_deleted'=>0])
  56. ->find();
  57. if(empty($goods_info)) $this->error('商品已下架');
  58. $spec_info = [];
  59. $goods_spec = json_decode($goods_info['spec'],true);
  60. foreach ($goods_spec as &$c){
  61. if($c['goods_no'] == $goods_no) {
  62. $spec_info =$c;
  63. $c['store_num'] -=$num;
  64. break;
  65. }
  66. }
  67. if($spec_info['store_num'] < $num || $goods_info['stock'] < $num) $this->error('商品库存不足');
  68. // 券验证
  69. if($cl_id) {
  70. $cl_info = Db::table('user_coupon_list')
  71. ->where(['user_id'=>$this->uid,'id'=>$cl_id,'status'=>1])
  72. ->find();
  73. if(empty($cl_info)) $this->error('优惠券不存在');
  74. if($cl_info['past_at'] < date('Y-m-d H:i:s')) $this->error('优惠券已过期');
  75. if($cl_info['low_amount'] > bcsub($price_total,$price_express,2) ) $this->error('订单金额不够,再看看吧');
  76. if($cl_info['amount'] != $coupon_cash ) $this->error('优惠金额错误');
  77. }
  78. // 积分验证
  79. $user = Db::table('store_member')->find($this->uid);
  80. if($integral && $user['integral'] < $integral) $this->error('积分余额不足');
  81. $pro_info[]=[
  82. 'goods_id' =>$goods_id,
  83. 'goods_no' =>$goods_no,
  84. 'num' => $num,
  85. 'integral' =>$spec_info['integral'] * $num,
  86. 'int_cash' =>$int_cash,
  87. 'sell_money'=>$spec_info['sell_money'],
  88. 'spec_exp' =>$spec_info['spec_exp'],
  89. 'spec_key' =>$spec_info['spec_key'],
  90. ];
  91. $order_int =[
  92. 'uid'=>$this->uid,
  93. 'order_no' => get_order_sn(),
  94. 'price_total' => $price_total,
  95. 'price_goods' => $price_goods,
  96. 'price_express' => $price_express,
  97. 'create_at' => date("Y-m-d H:i:s"),
  98. 'address_id' =>$add_id,
  99. 'source' =>$source,
  100. 'integral' =>$integral,
  101. 'int_cash' =>$int_cash,
  102. 'coupon_id' =>$cl_id,
  103. 'coupon_cash' =>$coupon_cash,
  104. 'remark' =>$remark,
  105. 'goods_num' =>$num,
  106. 'pro_info' =>json_encode($pro_info)
  107. ];
  108. Db::startTrans();
  109. $msg= '';$com=true;
  110. try{
  111. // 生成订单
  112. Db::table('store_order')->insert($order_int);
  113. $order_id = Db::getLastInsID();
  114. //扣减库存
  115. Db::table('store_goods')->where(['id'=>$goods_id])->update(['spec'=>json_encode($goods_spec),'stock'=>$goods_info['stock'] - $num]);
  116. //扣减积分
  117. if($integral){
  118. Db::table('store_member')->where(['id'=>$this->uid])->setDec('integral',$integral);
  119. //积分扣减记录
  120. $integral_info=[
  121. 'user_id'=> $this->uid,
  122. 'create_at'=> date("Y-m-d H:i:s"),
  123. 'integral'=> $integral*-1,
  124. 'before'=> $user['integral'],
  125. 'after'=> $user['integral'] - $integral,
  126. 'desc'=> '积分抵现',
  127. 'rel_id'=> $order_id,
  128. ];
  129. Db::table('integral_info')->insert($integral_info);
  130. }
  131. // 扣除券
  132. if($cl_id) {
  133. Db::table('user_coupon_list')->where(['id'=>$cl_id])->update(['status'=>2,'used_time'=>date('Y-m-d H:i:s')]);
  134. }
  135. Db::commit();
  136. }catch (\Exception $e){
  137. Db::rollback();
  138. $com=false;
  139. $msg = $e->getMessage();
  140. }
  141. if($com){
  142. $this->success('ok',['order_id'=>$order_id]);
  143. }else{
  144. $this->error($msg);
  145. }
  146. }
  147. /**
  148. * @title 生成订单(购物车)
  149. * @desc 生成订单(购物车)
  150. * @author qc
  151. * @url /api/Order/createOrderByTrolley
  152. * @method POST
  153. * @header name:Authorization require:1 desc:Token
  154. * @param name:ids type:string : default:1 desc:购物车记录id串(逗号分开)
  155. * @param name:price_total type:float require:1 default:-- desc:支付金额(优惠后的商品金额+运费)
  156. * @param name:price_goods type:float require:0 default:0 desc:商品总金额(没优惠的)
  157. * @param name:price_express type:float require:0 default:0 desc:运费
  158. * @param name:add_id type:int require:1 default:0 desc:收货地址id
  159. * @param name:remark type:string require:0 default:0 desc:订单备注
  160. * @param name:source type:int require:0 default:0 desc:商城的为0(默认),积分商城的值为1
  161. * @param name:integral type:int require:0 default:0 desc:使用多少积分,source为1时必传
  162. * @param name:int_cash type:float require:0 default:0 desc:积分抵扣多少钱,source为1时必传
  163. * @param name:cl_id type:int require:0 default:0 desc:会员优惠券id,使用优惠券必传
  164. * @param name:coupon_cash type:float require:0 default:0 desc:会员优惠券抵扣金额
  165. * @return name:order_id type:int require:0 default:0 desc:成功时返回订单id
  166. */
  167. public function createOrderByTrolley()
  168. {
  169. $ids = input("post.ids");
  170. $price_total = input("post.price_total");
  171. $price_goods = input("post.price_goods");
  172. $price_express = input("post.price_express");
  173. $add_id = input("post.add_id");
  174. $source = input("post.source",0);
  175. $integral = input("post.integral",0);
  176. $int_cash = input("post.int_cash",0);
  177. $cl_id = input("post.cl_id",0);
  178. $coupon_cash = input("post.coupon_cash",0);
  179. $remark = input("post.remark",0);
  180. if(!$ids) $this->error('请选择要结算的商品');
  181. $trolley_arr = Db::table('shopping_trolley')
  182. ->where(['uid'=>$this->uid,'id'=>explode(',',$ids)])
  183. ->select();
  184. $pro_info = [];$total_num = 0;$check_goods = true;
  185. // 验证商品是否下架 && 获取订单商品详情
  186. foreach ($trolley_arr as $tv) {
  187. $goods_info = Db::table('store_goods')->field('id,spec,name')
  188. ->where(['id'=>$tv['goods_id'],'is_deleted'=>0,'status'=>1])
  189. ->find();
  190. if(!empty($goods_info)){
  191. $check_goods =false;
  192. break;
  193. }
  194. foreach (json_decode($tv['spec'],true) as $sv)
  195. {
  196. if($sv['goods_no'] == $tv['goods_no']) {
  197. $pro_info[]=[
  198. 'goods_id' =>$tv['goods_id'],
  199. 'goods_no' =>$tv['goods_no'],
  200. 'num' =>$tv['num'],
  201. 'integral' =>$sv['integral'] * $tv['num'],
  202. 'int_cash' =>'--',
  203. 'sell_money'=>$sv['sell_money'],
  204. 'spec_exp' =>$sv['spec_exp'],
  205. 'spec_key' =>$sv['spec_key'],
  206. ];
  207. $total_num +=$tv['num'];
  208. }
  209. }
  210. }
  211. if(!$check_goods) $this->error('所选商品已下架');
  212. // 券验证
  213. if($cl_id) {
  214. $cl_info = Db::table('user_coupon_list')
  215. ->where(['user_id'=>$this->uid,'id'=>$cl_id,'status'=>1])
  216. ->find();
  217. if(empty($cl_info)) $this->error('优惠券不存在');
  218. if($cl_info['past_at'] < date('Y-m-d H:i:s')) $this->error('优惠券已过期');
  219. if($cl_info['low_amount'] > bcsub($price_total,$price_express,2) ) $this->error('订单金额不够,再看看吧');
  220. if($cl_info['amount'] != $coupon_cash ) $this->error('优惠金额错误');
  221. }
  222. // 积分验证
  223. $user = Db::table('store_member')->find($this->uid);
  224. if($integral && $user['integral'] < $integral) $this->error('积分余额不足');
  225. $order_int =[
  226. 'uid'=>$this->uid,
  227. 'order_no' => get_order_sn(),
  228. 'price_total' => $price_total,
  229. 'price_goods' => $price_goods,
  230. 'price_express' => $price_express,
  231. 'create_at' => date("Y-m-d H:i:s"),
  232. 'address_id' =>$add_id,
  233. 'source' =>$source,
  234. 'integral' =>$integral,
  235. 'int_cash' =>$int_cash,
  236. 'coupon_id' =>$cl_id,
  237. 'coupon_cash' =>$coupon_cash,
  238. 'remark' =>$remark,
  239. 'goods_num' =>$total_num,
  240. 'pro_info' =>json_encode($pro_info)
  241. ];
  242. Db::startTrans();
  243. $msg= '';$com=true;
  244. try{
  245. // 生成订单
  246. Db::table('store_order')->insert($order_int);
  247. $order_id = Db::getLastInsID();
  248. //扣减积分
  249. if($integral){
  250. Db::table('store_member')->where(['id'=>$this->uid])->setDec('integral',$integral);
  251. //积分扣减记录
  252. $integral_info=[
  253. 'user_id'=> $this->uid,
  254. 'create_at'=> date("Y-m-d H:i:s"),
  255. 'integral'=> $integral * -1,
  256. 'before'=> $user['integral'],
  257. 'after'=> $user['integral'] - $integral,
  258. 'desc'=> '积分抵现',
  259. 'rel_id'=> $order_id,
  260. ];
  261. Db::table('integral_info')->insert($integral_info);
  262. }
  263. // 扣除券
  264. if($cl_id) {
  265. Db::table('user_coupon_list')->where(['id'=>$cl_id])->update(['status'=>2,'used_time'=>date('Y-m-d H:i:s')]);
  266. }
  267. Db::commit();
  268. }catch (\Exception $e){
  269. Db::rollback();
  270. $com=false;
  271. $msg = $e->getMessage();
  272. }
  273. if($com){
  274. $this->success('ok',['order_id'=>$order_id]);
  275. }else{
  276. $this->error($msg);
  277. }
  278. }
  279. /**
  280. * @title 获取订单详情
  281. * @desc 获取订单详情
  282. * @author qc
  283. * @url /api/Order/getOrderDetail
  284. * @method GET
  285. * @header name:Authorization require:1 desc:Token
  286. * @param name:id type:int require:1 default:-- desc:订单id
  287. * @return name:order_no type:string default:-- desc:订单号
  288. * @return name:status type:int default:-- desc:支付状态:0待支付,1已支付,2待发货,3待收货,4已收货,5已完成,9取消
  289. * @return name:price_total type:float default:-- desc:订单金额(需要支付金额【包含运费,扣除所有优惠】)
  290. * @return name:price_goods type:float default:-- desc:商品金额
  291. * @return name:price_express type:float default:-- desc:运费
  292. * @return name:pay_state type:int default:-- desc:支付状态(0未支付,1已支付)
  293. * @return name:order_no type:string default:-- desc:订单号
  294. * @return name:pay_no type:string default:-- desc:支付单号
  295. * @return name:create_at type:string default:-- desc:订单创建时间
  296. * @return name:pay_at type:string default:-- desc:支付时间
  297. * @return name:cancel_at type:string default:-- desc:取消时间(status=9)
  298. * @return name:cancel_desc type:string default:-- desc:取消描述(status=9)
  299. * @return name:refund_type type:int default:-- desc:订单申请退款、退换货状态0未申请,1部分申请,2全部申请
  300. * @return name:source type:int default:0 desc:订单来源:0商城,1积分商城
  301. * @return name:integral type:int default:0 desc:使用多少积分
  302. * @return name:int_cash type:int default:0 desc:积分抵扣多少金额
  303. * @return name:cl_id type:int default:0 desc:使用优惠券的id
  304. * @return name:coupon_cash type:float default:0 desc:券抵扣金额
  305. */
  306. public function getOrderDetail()
  307. {
  308. $order_id = input('id',0);
  309. $detail = Db::table('store_order')->find($order_id);
  310. $this->success('获取成功',$detail);
  311. }
  312. public function getOrderReturn()
  313. {
  314. }
  315. /**
  316. * 获取退款订单详情
  317. * @param $order_id
  318. */
  319. public function getReturnDetail($order_id)
  320. {
  321. $return_detail = Db::table('order_return')
  322. ->find($order_id);
  323. return $return_detail;
  324. }
  325. /**
  326. * @title 去支付
  327. * @desc 去支付
  328. * @author qc
  329. * @url /api/Order/payOrder
  330. * @method POST
  331. * @header name:Authorization require:1 desc:Token
  332. * @param name:o_id type:int require:1 default:-- desc:订单id
  333. * @param name:is_remind type:int require:1 default:0 desc:订单是否提醒,0不提醒,1提醒
  334. */
  335. public function payOrder()
  336. {
  337. $o_id = input('post.o_id');
  338. $is_remind = input('post.is_remind');
  339. $user_info = Db::table('store_member')->where('id',$this->uid)->find();
  340. if(!$user_info['phone'] || !$user_info['openid']) $this->error('请先完善用户信息');
  341. $order_info = Db::table('ticket_order')->where(['uid'=>$this->uid,'id'=>$o_id,'cancel_state'=>0])->find();
  342. if(empty($order_info)) $this->error('订单不存在');
  343. if($order_info['price_total'] <= 0 ) $this->error('订单金额错误');
  344. if($order_info['status'] != 0 ) $this->error('订单状态错误');
  345. Db::startTrans();
  346. $config = false;$msg= '';
  347. try{
  348. $notify_url = $this->request->root(true) . '/api/Pay/payNotify';
  349. $pay_no = get_order_sn();
  350. Db::table('ticket_order')
  351. ->where(['uid'=>$this->uid,'id'=>$o_id])
  352. ->update(['is_remind'=>$is_remind,'pay_no'=>$pay_no]);
  353. $config = Pay::wxPay('订单支付',$pay_no,$order_info['price_total'],$notify_url,'JSAPI',$user_info['openid']);
  354. if($config){
  355. Db::commit();
  356. }else{
  357. Db::rollback();
  358. }
  359. }catch (\Exception $e){
  360. Db::rollback();
  361. $msg = $e->getMessage();
  362. }
  363. if($config){
  364. $this->success('ok',['jump'=>1,'config'=>$config]);
  365. }else{
  366. $this->error($msg);
  367. }
  368. }
  369. /**
  370. * @title 获取订单列表
  371. * @desc 获取订单列表
  372. * @author qc
  373. * @url /api/Order/getMyOrderList
  374. * @method GET
  375. * @header name:Authorization require:1 desc:Token
  376. * @param name:type type:int : default:1 desc:查询类型,1所有,2待核销,3待评价,4已完成
  377. * @param name:page type:int : default:1 desc:页数
  378. * @param name:page_num type:int : default:20 desc:每页数
  379. * @return name:order_no type:string default:-- desc:订单号
  380. * @return name:total_num type:int default:-- desc:订单总票数(包含儿童票)
  381. * @return name:children_num type:int default:-- desc:儿童票数
  382. * @return name:pay_state type:int default:-- desc:支付状态(0未支付,1已支付)
  383. * @return name:price_total type:float default:-- desc:订单金额
  384. * @return name:create_at type:string default:-- desc:订单创建时间
  385. * @return name:tel type:string default:-- desc:订单预留电话
  386. * @return name:remark type:string default:-- desc:备注
  387. * @return name:f_id type:string default:-- desc:电影id
  388. * @return name:film_name type:string default:-- desc:电影名称
  389. * @return name:cover type:string default:-- desc:电影封面
  390. * @return name:duration type:string default:-- desc:电影时长(分钟)
  391. * @return name:day_time type:string default:-- desc:播放时间(天)
  392. * @return name:point_time type:string default:-- desc:电影播放时间(点)
  393. * @return name:end_time type:string default:-- desc:播放结束时间(点)
  394. * @return name:qrcode type:string default:-- desc:核销码
  395. * @return name:is_hx type:int default:0 desc:是否核销
  396. * @return name:is_discuss type:int default:0 desc:是否评价
  397. * @return name:ticket_price type:float default:0 desc:票价(成人)
  398. */
  399. public function getMyOrderList()
  400. {
  401. $type = input('type',1);
  402. $page = input('page',1);
  403. $page_num = input('page_num',20);
  404. $off_set = $page*$page_num - $page_num;
  405. $where=[];
  406. $where['o.uid'] = $this->uid;
  407. $where['o.pay_state'] = 1;
  408. switch ($type)
  409. {
  410. case 1: // 全部
  411. break;
  412. case 2: // 待核销
  413. $where['o.is_hx'] = 0;
  414. break;
  415. case 3:// 待评价
  416. $where['o.is_discuss'] = 0;
  417. $where['o.is_hx'] = 1;
  418. break;
  419. case 4:// 已完成
  420. $where['o.is_discuss'] = 1;
  421. $where['o.is_hx'] = 1;
  422. break;
  423. }
  424. $list = Db::table('ticket_order o')
  425. ->field('o.id,o.total_num,order_no,o.pay_state,o.create_at,children_num,pay_at,o.price_total,o.tel,o.remark,o.is_hx,o.ticket_price,o.is_discuss,f.name as film_name,o.qrcode ,o.f_id,f.duration,f.desc as film_desc,f.cover,s.day_time,s.point_time')
  426. ->join('film_list f',' o.f_id = f.id ','LEFT')
  427. ->join('film_info s',' o.s_id = s.id ','LEFT')
  428. ->where($where)
  429. ->order('o.id desc')
  430. ->limit($off_set,$page_num)
  431. ->select();
  432. $this->success('获取成功',$list);
  433. }
  434. /**
  435. * @title 取消订单
  436. * @desc 取消订单
  437. * @author qc
  438. * @url /api/Order/cancelOrder
  439. * @method POST
  440. * @header name:Authorization require:1 desc:Token
  441. * @param name:id type:int require:1 default:-- desc:订单id
  442. * @param name:desc type:string require:1 default:-- desc:取消描述
  443. * @param name:is_remind type:int require:1 default:0 desc:订单是否提醒,0不提醒,1提醒
  444. */
  445. public function cancelOrder()
  446. {
  447. $o_id = input('post.id');
  448. $desc = input('post.desc');
  449. $order_detail = Db::table('ticket_order')->where(['id'=>$o_id])->find($o_id);
  450. if(empty($order_detail)) $this->error('订单不存在');
  451. if($order_detail['pay_state'] != 0) $this->error('订单已支付');
  452. if($order_detail['cancel_state'] != 0) $this->error('订单已取消,不能重复取消');
  453. Db::startTrans();
  454. try {
  455. Db::table('ticket_order')->where(['id'=>$o_id])->update(['cancel_state'=>1,'cancel_at'=>date('Y-m-d H:i:s'),'desc'=>$desc]);
  456. Db::table('film_info')->where('id', $order_detail['s_id'])->setInc('surplus_num', $order_detail['total_num']);//增加场次余票
  457. Db::commit();
  458. }catch (\Exception $e){
  459. Db::rollback();
  460. }
  461. $this->success('取消成功');
  462. }
  463. }