Order.php 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  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::initialize();
  15. parent::check_login();
  16. }
  17. /**
  18. * @title 订单确认(直接购买&&直接兑换)
  19. * @desc 生成订单
  20. * @author qc
  21. * @url /api/Order/orderConfirm
  22. * @method GET
  23. * @header name:Authorization require:1 desc:Token
  24. * @param name:goods_id type:int require:1 default:-- desc:商品id
  25. * @param name:goods_no type:string require:1 default:-- desc:商品货号
  26. * @param name:num type:int require:0 default:1 desc:商品数量
  27. * @return name:add_info type:array require:0 default:-- desc:默认地址
  28. * @return name:add_info.id type:int default:1 desc:收货地址记录id
  29. * @return name:add_info.pro_id type:int default:-- desc:省id
  30. * @return name:add_info.city_id type:int default:-- desc:市id
  31. * @return name:add_info.county_id type:int default:-- desc:县区id
  32. * @return name:add_info.pro_name type:string default:-- desc:省名
  33. * @return name:add_info.city_name type:string default:-- desc:市名
  34. * @return name:add_info.county_name type:string default:-- desc:县区名
  35. * @return name:add_info.detail type:string default:-- desc:详细地址
  36. * @return name:add_info.phone type:string default:-- desc:联系电话
  37. * @return name:add_info.name type:string default:-- desc:联系人
  38. * @return name:goods_data type:array require:0 default:-- desc:商品详情
  39. * @return name:goods_data.goods_id type:array require:0 default:-- desc:商品id
  40. * @return name:goods_data.name type:string require:0 default:-- desc:商品名称
  41. * @return name:goods_data.cover type:string require:0 default:-- desc:商品图片
  42. * @return name:goods_data.freight type:float require:0 default:-- desc:商品运费
  43. * @return name:goods_data.sell_money type:float require:0 default:-- desc:售价
  44. * @return name:goods_data.integral type:int require:0 default:-- desc:商品积分数(单个商品积分乘以个数)
  45. */
  46. public function orderConfirm()
  47. {
  48. $goods_id = input('get.goods_id');
  49. $goods_no = input('get.goods_no');
  50. $num = input('get.num',1);
  51. $add_info = Db::table('delivery_address')
  52. ->where(['user_id'=>$this->uid,'is_mr'=>1])->find();
  53. $goods_info = Db::table('store_goods')->find($goods_id);
  54. $spec = json_decode($goods_info['spec'],true);
  55. $cover = $goods_info['cover'];
  56. $sell_money = 0;
  57. foreach ($spec as $sk=>$sv)
  58. {
  59. if($goods_no == $sv['goods_no']){
  60. $cover = $sv['spec_img'];
  61. $sell_money = $sv['sell_money'];
  62. }
  63. }
  64. $freight = $goods_info['freight_type'] == 0 ? $goods_info['postage'] :0 ;
  65. // 运费模板计算运费
  66. if(!empty($add_info) && $goods_info['freight_type']){
  67. $cal_freight = $this->claFreight($add_info['id'],$goods_info['freight_id'],$num);
  68. if($cal_freight['code'] != 200){
  69. $add_info = null ;
  70. }else{
  71. $freight = $cal_freight['freight'];
  72. }
  73. }
  74. $goods_data = [
  75. 'goods_id' => $goods_info['id'],
  76. 'goods_no' => $goods_no,
  77. 'name' => $goods_info['name'],
  78. 'cover' => $cover,
  79. 'integral'=>$goods_info['integral'] * $num,
  80. 'freight' => $freight,
  81. 'sell_money' => $sell_money,
  82. ];
  83. $this->success('ok',['add_info'=> $add_info ,'goods_data'=>$goods_data]);
  84. }
  85. /**
  86. * 计算运费
  87. * @param $add_id 地址id
  88. * @param $freight_id 模板id
  89. * @param $num 商品数量
  90. * @return array
  91. */
  92. public function claFreight($add_id,$freight_id,$num)
  93. {
  94. $data = ['code'=>200,'freight'=>0 ,'msg'=>''];
  95. $address_info = Db::table('delivery_address')->find($add_id);
  96. $template_info = Db::table('freight_template')->find($freight_id);
  97. if(empty($address_info)){
  98. $data['code'] = 201;
  99. $data['msg'] = '运费模板不存在';
  100. return $data;
  101. }
  102. $city_id = $address_info['city_id'];
  103. $no_express = explode(',',$template_info['no_express']);
  104. if(in_array($city_id,$no_express)) return ['code'=>202,'msg'=>'该收货地址不配送物流'];
  105. // 模板自定义分组
  106. $custom = json_decode($template_info['custom'],true);
  107. $base_num = $template_info['base_num'];// 基件数量
  108. $base_price = $template_info['base_price']; // 基件费用
  109. $base_keep_price = $template_info['base_keep_price']; // 续件费用
  110. foreach($custom as $cus_info) {
  111. $express =explode(',',$cus_info['express']);
  112. if(in_array($city_id,$express)) {
  113. $base_num = $cus_info['first_num'];
  114. $base_price = $cus_info['first_price'];
  115. $base_keep_price = $cus_info['keep_price'];
  116. break;
  117. }
  118. }
  119. if($base_num >= $num ) return $data = ['code'=>200,'freight'=>$base_price ,'msg'=>'ok'];
  120. $sub_keep = bcmul(bcsub($num,$base_num),$base_keep_price,2);
  121. return $data = ['code'=>200,'freight'=>bcadd($base_price,$sub_keep) ,'msg'=>'ok'];
  122. }
  123. /**
  124. * @title 获取运费
  125. * @desc 获取运费
  126. * @author qc
  127. * @url /api/Order/getFreight
  128. * @method GET
  129. * @header name:Authorization require:1 desc:Token
  130. * @param name:goods_id type:int require:1 default:-- desc:商品id
  131. * @param name:add_id type:int require:1 default:-- desc:地址id
  132. * @param name:num type:int require:0 default:1 desc:商品数量
  133. * @return name:freight type:float require:0 default:-- desc:运费金额
  134. */
  135. public function getFreight()
  136. {
  137. $goods_id = input('goods_id',0);
  138. $add_id = input('add_id',0);
  139. $num = input('num',0);
  140. $goods_info = Db::table('store_goods')->find($goods_id);
  141. $freight = $goods_info['freight_type'] == 0 ? $goods_info['postage'] :0 ;
  142. if($goods_info['freight_type']){
  143. $cal_freight = $this->claFreight($add_id,$goods_info['freight_id'],$num);
  144. if($cal_freight['code'] != 200){
  145. $this->error($cal_freight['msg']);
  146. }else{
  147. $freight = $cal_freight['freight'];
  148. }
  149. }
  150. $this->success('ok',['freight'=>$freight]);
  151. }
  152. /**
  153. * @title 生成订单(立即购买 [商城 && 积分商城])
  154. * @desc 生成订单(立即购买 [商城 && 积分商城])
  155. * @author qc
  156. * @url /api/Order/createOrderByImmediately
  157. * @method POST
  158. * @header name:Authorization require:1 desc:Token
  159. * @param name:goods_id type:int require:1 default:-- desc:商品id
  160. * @param name:goods_no type:int require:1 default:-- desc:商品货号
  161. * @param name:price_total type:float require:1 default:-- desc:支付金额(优惠后的商品金额+运费)
  162. * @param name:num type:int require:1 default:1 desc:商品数量
  163. * @param name:price_goods type:float require:0 default:0 desc:商品总金额(没优惠的)
  164. * @param name:price_express type:float require:0 default:0 desc:运费
  165. * @param name:add_id type:int require:1 default:0 desc:收货地址id
  166. * @param name:remark type:string require:0 default:0 desc:订单备注
  167. * @param name:source type:int require:0 default:0 desc:商城的为0(默认),积分商城的值为1
  168. * @param name:integral type:int require:0 default:0 desc:使用多少积分,source为1时必传
  169. * @return name:order_id type:int require:0 default:0 desc:成功时返回订单id
  170. */
  171. public function createOrderByImmediately()
  172. {
  173. $goods_id = input("post.goods_id");
  174. $goods_no = input("post.goods_no");
  175. $price_total = input("post.price_total",0);
  176. $price_goods = input("post.price_goods",0);
  177. $price_express = input("post.price_express",0);
  178. $num = input("post.num",1);
  179. $add_id = input("post.add_id",0);
  180. $source = input("post.source",0);
  181. $integral = input("post.integral",0);
  182. $int_cash = input("post.int_cash",0);
  183. $cl_id = input("post.cl_id",0);
  184. $coupon_cash = input("post.coupon_cash",0);
  185. $remark = input("post.remark",'');
  186. //商品验证start
  187. $goods_info = Db::table('store_goods')->field('id,name,spec,stock,is_integral,level')
  188. ->where(['id'=>$goods_id,'status'=>1,'is_deleted'=>0])
  189. ->find();
  190. if(empty($goods_info)) $this->error('商品已下架');
  191. $send_info = Db::table('delivery_address')->field('pro_name,city_name,county_name,mer_name,detail,phone,name')->find($add_id);
  192. $source = $goods_info['is_integral'];
  193. $spec_info = [];
  194. $goods_spec = json_decode($goods_info['spec'],true);
  195. foreach ($goods_spec as &$c){
  196. if($c['goods_no'] == $goods_no) {
  197. $spec_info =$c;
  198. $c['store_num'] -=$num;
  199. break;
  200. }
  201. }
  202. if(!isset($spec_info['integral'])) $spec_info['integral'] = 0;
  203. if($spec_info['store_num'] < $num || $goods_info['stock'] < $num) $this->error('商品库存不足');
  204. // 券验证
  205. if($cl_id) {
  206. $cl_info = Db::table('user_coupon_list')
  207. ->where(['user_id'=>$this->uid,'id'=>$cl_id,'status'=>1])
  208. ->find();
  209. if(empty($cl_info)) $this->error('优惠券不存在');
  210. if($cl_info['past_at'] < date('Y-m-d H:i:s')) $this->error('优惠券已过期');
  211. if($cl_info['low_amount'] > bcsub($price_total,$price_express,2) ) $this->error('订单金额不够,再看看吧');
  212. if($cl_info['amount'] != $coupon_cash ) $this->error('优惠金额错误');
  213. }
  214. // 积分验证
  215. $user = Db::table('store_member')->find($this->uid);
  216. if($goods_info['level'] > $user['level_id'])$this->error('等级限制,无法购买!');
  217. if($integral && $user['integral'] < $integral) $this->error('积分余额不足');
  218. $pro_info[]=[
  219. 'goods_id' =>$goods_id,
  220. 'goods_no' =>$goods_no,
  221. 'num' => $num,
  222. 'integral' =>$spec_info['integral'] * $num,
  223. 'int_cash' =>$int_cash,
  224. 'goods_name' =>$goods_info['name'],
  225. 'spec_img' =>$spec_info['spec_img'],
  226. 'sell_money'=>$spec_info['sell_money'],
  227. 'spec_exp' =>$spec_info['spec_exp'],
  228. 'spec_key' =>$spec_info['spec_key'],
  229. 'is_evaluate' => 0,
  230. ];
  231. $order_int =[
  232. 'uid'=>$this->uid,
  233. 'order_no' => get_order_sn(),
  234. 'price_total' => $price_total,
  235. 'price_goods' => $price_goods,
  236. 'price_express' => $price_express,
  237. 'create_at' => date("Y-m-d H:i:s"),
  238. 'address_id' =>$add_id,
  239. 'source' =>$source,
  240. 'integral' =>$integral,
  241. 'int_cash' =>$int_cash,
  242. 'cl_id' =>$cl_id,
  243. 'coupon_cash' =>$coupon_cash,
  244. 'remark' =>$remark,
  245. 'goods_num' =>$num,
  246. 'pro_info' =>json_encode($pro_info),
  247. 'send_info' =>json_encode($send_info)
  248. ];
  249. Db::startTrans();
  250. $msg= '';$com=true;
  251. try{
  252. // 生成订单
  253. Db::table('store_order')->insert($order_int);
  254. $order_id = Db::getLastInsID();
  255. //扣减库存
  256. update_goods_stock($goods_id,$goods_no,$num);
  257. //扣减积分
  258. if($integral){
  259. update_user_integral($this->uid,$integral * -1,5,'积分抵扣',$order_id);
  260. }
  261. // 扣除券
  262. if($cl_id) {
  263. Db::table('user_coupon_list')->where(['id'=>$cl_id])->update(['status'=>2,'used_time'=>date('Y-m-d H:i:s')]);
  264. }
  265. Db::commit();
  266. }catch (\Exception $e){
  267. Db::rollback();
  268. $com=false;
  269. $msg = $e->getMessage();
  270. }
  271. if($com){
  272. $this->success('ok',['order_id'=>$order_id]);
  273. }else{
  274. $this->error($msg);
  275. }
  276. }
  277. /**
  278. * @title 取消订单
  279. * @desc 取消订单
  280. * @author qc
  281. * @url /api/Order/cancelOrder
  282. * @method POST
  283. * @header name:Authorization require:1 desc:Token
  284. * @param name:id type:int require:1 default:-- desc:订单id
  285. * @param name:cancel_desc type:string require:1 default:-- desc:取消描述
  286. */
  287. public function cancelOrder()
  288. {
  289. $order_id = input('post.id');
  290. $desc = input('post.desc');
  291. $order_detail = Db::table('store_order')->where(['id'=>$order_id])->find();
  292. if(empty($order_detail)) $this->error('订单不存在');
  293. if($order_detail['pay_state'] != 0) $this->error('订单已支付');
  294. if($order_detail['cancel_state'] != 0) $this->error('订单已取消,不能重复取消');
  295. Db::startTrans();
  296. try {
  297. // 积分退回
  298. if($order_detail['integral'] > 0) {
  299. update_user_integral($order_detail['uid'],$order_detail['integral'],8,'订单取消退回',$order_id);
  300. }
  301. // 优惠券回档
  302. if($order_detail['cl_id'] > 0) {
  303. $user_coupon = Db::table('user_coupon_list')->find($order_detail['cl_id']);// 会员优惠券记录
  304. $coupon_set = Db::table('store_coupon_config')->find($user_coupon['coupon_id']);//优惠券设置
  305. if($coupon_set['status'] != 1 || $coupon_set['is_deleted'] == 1){
  306. $coupon_status = 4;
  307. }else{
  308. $coupon_status = $user_coupon['past_at'] > date("Y-m-d H:i:s") ? 1:3;
  309. }
  310. Db::table('user_coupon_list')->where(['id'=>$order_detail['cl_id']])->update(['status'=>$coupon_status]);
  311. }
  312. // 商品库存恢复
  313. $pro_info = json_decode($order_detail['pro_info'],true);
  314. foreach ($pro_info as $pv) {
  315. update_goods_stock($pv['goods_id'],$pv['goods_no'],$pv['num']*-1);
  316. }
  317. // 取消订单
  318. Db::table('store_order')
  319. ->where(['id'=>$order_id])
  320. ->update(['cancel_state'=>1,'cancel_at'=>date('Y-m-d H:i:s'),'cancel_desc'=>$desc,'status'=>9]);
  321. Db::commit();
  322. }catch (\Exception $e){
  323. Db::rollback();
  324. }
  325. $this->success('取消成功');
  326. }
  327. /**
  328. * @title 生成订单(购物车)
  329. * @desc 生成订单(购物车)
  330. * @author qc
  331. * @url /api/Order/createOrderByTrolley
  332. * @method POST
  333. * @header name:Authorization require:1 desc:Token
  334. * @param name:ids type:string : default:1 desc:购物车记录id串(逗号分开)
  335. * @param name:price_total type:float require:1 default:-- desc:支付金额(优惠后的商品金额+运费)
  336. * @param name:price_goods type:float require:0 default:0 desc:商品总金额(没优惠的)
  337. * @param name:price_express type:float require:0 default:0 desc:运费
  338. * @param name:add_id type:int require:1 default:0 desc:收货地址id
  339. * @param name:remark type:string require:0 default:0 desc:订单备注
  340. * @param name:source type:int require:0 default:0 desc:商城的为0(默认),积分商城的值为1
  341. * @param name:integral type:int require:0 default:0 desc:使用多少积分,source为1时必传
  342. * @param name:int_cash type:float require:0 default:0 desc:积分抵扣多少钱,source为1时必传
  343. * @param name:cl_id type:int require:0 default:0 desc:会员优惠券id,使用优惠券必传
  344. * @param name:coupon_cash type:float require:0 default:0 desc:会员优惠券抵扣金额
  345. * @return name:order_id type:int require:0 default:0 desc:成功时返回订单id
  346. */
  347. public function createOrderByTrolley()
  348. {
  349. $ids = input("post.ids");
  350. $price_total = input("post.price_total",0);
  351. $price_goods = input("post.price_goods",0);
  352. $price_express = input("post.price_express",0);
  353. $add_id = input("post.add_id",0);
  354. $source = input("post.source",0);
  355. $integral = input("post.integral",0);
  356. $int_cash = input("post.int_cash",0);
  357. $cl_id = input("post.cl_id",0);
  358. $coupon_cash = input("post.coupon_cash",0);
  359. $remark = input("post.remark",'');
  360. if(!$ids || !$price_total) $this->error('请选择要结算的商品');
  361. $trolley_arr = Db::table('shopping_trolley')
  362. ->where(['user_id'=>$this->uid,'id'=>explode(',',$ids)])
  363. ->select();
  364. $send_info = Db::table('delivery_address')->field('pro_name,city_name,county_name,mer_name,detail,phone,name')->find($add_id);
  365. $pro_info = [];$total_num = 0;$check_goods = true;
  366. // 验证商品是否下架 && 获取订单商品详情
  367. foreach ($trolley_arr as $tv) {
  368. $goods_info = Db::table('store_goods')->field('id,spec,name')
  369. ->where(['id'=>$tv['goods_id'],'is_deleted'=>0,'status'=>1])
  370. ->find();
  371. if(empty($goods_info)){
  372. $check_goods =false;
  373. break;
  374. }
  375. foreach (json_decode($goods_info['spec'],true) as $sv)
  376. {
  377. if($sv['goods_no'] == $tv['goods_no']) {
  378. $pro_info[]=[
  379. 'goods_id' =>$tv['goods_id'],
  380. 'goods_no' =>$tv['goods_no'],
  381. 'num' =>$tv['num'],
  382. 'integral' => isset($sv['integral']) ? $sv['integral'] * $tv['num'] : 0,
  383. 'int_cash' =>'--',
  384. 'goods_name' =>$goods_info['name'],
  385. 'spec_img' =>$sv['spec_img'],
  386. 'sell_money'=>$sv['sell_money'],
  387. 'spec_exp' =>$sv['spec_exp'],
  388. 'spec_key' =>$sv['spec_key'],
  389. 'is_evaluate' => 0,
  390. ];
  391. $total_num +=$tv['num'];
  392. }
  393. }
  394. }
  395. if(!$check_goods) $this->error('所选商品已下架');
  396. // 券验证
  397. if($cl_id) {
  398. $cl_info = Db::table('user_coupon_list')
  399. ->where(['user_id'=>$this->uid,'id'=>$cl_id,'status'=>1])
  400. ->find();
  401. if(empty($cl_info)) $this->error('优惠券不存在');
  402. if($cl_info['past_at'] < date('Y-m-d H:i:s')) $this->error('优惠券已过期');
  403. if($cl_info['low_amount'] > bcsub($price_total,$price_express,2) ) $this->error('订单金额不够,再看看吧');
  404. if($cl_info['amount'] != $coupon_cash ) $this->error('优惠金额错误');
  405. }
  406. // 积分验证
  407. $user = Db::table('store_member')->find($this->uid);
  408. if($integral && $user['integral'] < $integral) $this->error('积分余额不足');
  409. $order_int =[
  410. 'uid'=>$this->uid,
  411. 'order_no' => get_order_sn(),
  412. 'price_total' => $price_total,
  413. 'price_goods' => $price_goods,
  414. 'price_express' => $price_express,
  415. 'create_at' => date("Y-m-d H:i:s"),
  416. 'address_id' =>$add_id,
  417. 'source' =>$source,
  418. 'integral' =>$integral,
  419. 'int_cash' =>$int_cash,
  420. 'cl_id' =>$cl_id,
  421. 'coupon_cash' =>$coupon_cash,
  422. 'remark' =>$remark,
  423. 'goods_num' =>$total_num,
  424. 'pro_info' =>json_encode($pro_info),
  425. 'send_info' =>json_encode($send_info)
  426. ];
  427. Db::startTrans();
  428. $msg= '';$com=true;
  429. try{
  430. // 生成订单
  431. Db::table('store_order')->insert($order_int);
  432. $order_id = Db::getLastInsID();
  433. // 删除购物车记录
  434. Db::table('shopping_trolley')->where(['id'=>explode(',',$ids)])->delete();
  435. //扣减积分
  436. if($integral){
  437. Db::table('store_member')->where(['id'=>$this->uid])->setDec('integral',$integral);
  438. //积分扣减记录
  439. $integral_info=[
  440. 'user_id'=> $this->uid,
  441. 'create_at'=> date("Y-m-d H:i:s"),
  442. 'integral'=> $integral * -1,
  443. 'before'=> $user['integral'],
  444. 'after'=> $user['integral'] - $integral,
  445. 'desc'=> '积分抵现',
  446. 'rel_id'=> $order_id,
  447. ];
  448. Db::table('integral_info')->insert($integral_info);
  449. }
  450. // 扣除券
  451. if($cl_id) {
  452. Db::table('user_coupon_list')->where(['id'=>$cl_id])->update(['status'=>2,'used_time'=>date('Y-m-d H:i:s')]);
  453. }
  454. Db::commit();
  455. }catch (\Exception $e){
  456. Db::rollback();
  457. $com=false;
  458. $msg = $e->getMessage();
  459. }
  460. if($com){
  461. $this->success('ok',['order_id'=>$order_id]);
  462. }else{
  463. $this->error($msg);
  464. }
  465. }
  466. /**
  467. * @title 获取订单详情
  468. * @desc 获取订单详情
  469. * @author qc
  470. * @url /api/Order/getOrderDetail
  471. * @method GET
  472. * @header name:Authorization require:1 desc:Token
  473. * @param name:id type:int require:1 default:-- desc:订单id
  474. * @return name:order_no type:string default:-- desc:订单号
  475. * @return name:status type:int default:-- desc:支付状态:0待支付,1已支付(待发货),2已发货(待收货),3已收货(待评论)4已完成,9取消
  476. * @return name:price_total type:float default:-- desc:订单金额(需要支付金额【包含运费,扣除所有优惠】)
  477. * @return name:pro_info type:string default:-- desc:订单商品
  478. * @return name:pro_info.goods_id type:int default:-- desc:商品id
  479. * @return name:pro_info.goods_no type:string default:-- desc:商品货号
  480. * @return name:pro_info.sell_money type:string default:-- desc:售价
  481. * @return name:pro_info.spec_img type:string default:-- desc:封面
  482. * @return name:pro_info.is_evaluate type:string default:-- desc:商品是否评价
  483. * @return name:price_goods type:float default:-- desc:商品金额
  484. * @return name:price_express type:float default:-- desc:运费
  485. * @return name:pay_state type:int default:-- desc:支付状态(0未支付,1已支付)
  486. * @return name:order_no type:string default:-- desc:订单号
  487. * @return name:pay_no type:string default:-- desc:支付单号
  488. * @return name:create_at type:string default:-- desc:订单创建时间
  489. * @return name:pay_at type:string default:-- desc:支付时间
  490. * @return name:cancel_at type:string default:-- desc:取消时间(status=9)
  491. * @return name:cancel_desc type:string default:-- desc:取消描述(status=9)
  492. * @return name:refund_type type:int default:-- desc:订单申请退款、退换货状态0未申请,1部分申请,2全部申请
  493. * @return name:source type:int default:0 desc:订单来源:0商城,1积分商城
  494. * @return name:integral type:int default:0 desc:使用多少积分
  495. * @return name:address_area type:string default:0 desc:收货地区(精确到县区)
  496. * @return name:address_detail type:string default:0 desc:详细地址
  497. * @return name:address_user type:string default:0 desc:收货人姓名
  498. * @return name:address_tel type:string default:0 desc:收货人电话
  499. */
  500. public function getOrderDetail()
  501. {
  502. $order_id = input('id',0);
  503. $detail = Db::table('store_order')->find($order_id);
  504. $add_info = json_decode($detail['send_info'],true);
  505. $detail['address_area'] = $add_info['mer_name'];
  506. $detail['address_detail'] = $add_info['detail'];
  507. $detail['address_user'] = $add_info['name'];
  508. $detail['address_tel'] = $add_info['phone'];
  509. $this->success('获取成功',$detail);
  510. }
  511. /**
  512. * @title 去支付
  513. * @desc 去支付
  514. * @author qc
  515. * @url /api/Order/payOrder
  516. * @method POST
  517. * @header name:Authorization require:1 desc:Token
  518. * @param name:o_id type:int require:1 default:-- desc:订单id
  519. * @return name:type type:int default:0 desc:类型(1.type=1,调支付,2纯积分兑换成功)
  520. * @return name:config type:array default:0 desc:支付配置(type=2时忽略)
  521. * @return name:config.appId type:string default:-- desc:公众账号ID
  522. * @return name:config.nonceStr type:string default:-- desc:随机字符串
  523. * @return name:config.signType type:string default:-- desc:签名类型
  524. * @return name:config.paySign type:string default:-- desc:签名
  525. * @return name:config.timestamp type:string default:-- desc:时间戳
  526. */
  527. public function payOrder()
  528. {
  529. $o_id = input('post.o_id');
  530. $user_info = Db::table('store_member')->where('id',$this->uid)->find();
  531. if( !$user_info['openid']) $this->error('请先完善用户信息');
  532. $order_info = Db::table('store_order')->where(['uid'=>$this->uid,'id'=>$o_id])->find();
  533. if(empty($order_info)) $this->error('订单不存在');
  534. if($order_info['status'] != 0) $this->error('订单已支付');
  535. if($order_info['cancel_state'] != 0) $this->error('订单已取消');
  536. if($order_info['price_total'] <= 0 && $order_info['source'] == 0) $this->error('订单金额错误');
  537. // 纯积分兑换
  538. if($order_info['price_total'] <= 0 && $order_info['source'] == 1 )
  539. {
  540. // 销量
  541. $sell_data = [];
  542. foreach (json_decode($order_info['pro_info'],true) as $pv){
  543. $sell_data[] =[
  544. 'goods_id' => $pv['goods_id'],
  545. 'goods_no' => $pv['goods_no'],
  546. 'num' => $pv['num'],
  547. 'user_id' => $order_info['uid'],
  548. 'order_id' => $order_info['id'],
  549. 'create_at' => date('Y-m-d H:i:s'),
  550. 'year' => date('Y'),
  551. 'month' => date('m'),
  552. 'day' => date('d'),
  553. ];
  554. }
  555. $pay_no = $order_info['pay_no'] ? $order_info['pay_no'] : get_order_sn();
  556. Db::table('goods_sell_info')->insertAll($sell_data);
  557. // 更新订单状态
  558. Db::table('store_order')->where(['uid'=>$this->uid,'id'=>$o_id])
  559. ->update(['pay_at'=>date('Y-m-d H:i:s'),'pay_state'=>1,'status'=>1,'pay_no'=>$pay_no]);
  560. $this->success('兑换成功',['type'=>2]);
  561. }else{
  562. Db::startTrans();
  563. $config = false;$msg= '';
  564. try{
  565. $notify_url = $this->request->root(true) . '/api/Pay/payNotify';
  566. $pay_no = $order_info['pay_no'] ? $order_info['pay_no'] : get_order_sn();
  567. Db::table('store_order')->where(['uid'=>$this->uid,'id'=>$o_id])->update(['pay_no'=>$pay_no]);
  568. $config = Pay::wxPay('订单支付',$pay_no,$order_info['price_total'],$notify_url,'JSAPI',$user_info['openid']);
  569. if($config){
  570. Db::commit();
  571. }else{
  572. Db::rollback();
  573. }
  574. }catch (\Exception $e){
  575. Db::rollback();
  576. $msg = $e->getMessage();
  577. }
  578. if($config){
  579. $this->success('ok',['type'=>1,'jump'=>1,'config'=>$config]);
  580. }else{
  581. $this->error($msg);
  582. }
  583. }
  584. }
  585. /**
  586. * @title 获取订单列表
  587. * @desc 获取订单列表
  588. * @author qc
  589. * @url /api/Order/getMyOrderList
  590. * @method GET
  591. * @header name:Authorization require:1 desc:Token
  592. * @param name:page type:int : default:1 desc:页数
  593. * @param name:page_num type:int : default:20 desc:每页数
  594. * @param name:status type:int : default:-1 desc:订单状态(-1全部,0待支付,1已支付(待发货),2已发货(待收货),3已收货(待评论)4已完成,9取消)
  595. * @return name:order_no type:string default:-- desc:订单号
  596. * @return name:pay_state type:int default:-- desc:支付状态(0未支付,1已支付)
  597. * @return name:status type:int default:-- desc:订单状态(0待支付,1已支付(待发货),2已发货(待收货),3已收货(待评论)4已完成,9取消)
  598. * @return name:price_total type:float default:-- desc:订单金额
  599. * @return name:pro_info type:float default:-- desc:订单详情
  600. * @return name:pro_info.goods_id type:int default:-- desc:商品id
  601. * @return name:pro_info.goods_name type:int default:-- desc:商品名
  602. * @return name:pro_info.goods_no type:string default:-- desc:商品货号
  603. * @return name:pro_info.sell_money type:string default:-- desc:售价
  604. * @return name:pro_info.spec_img type:string default:-- desc:封面
  605. * @return name:pro_info.is_evaluate type:string default:-- desc:商品是否评价
  606. * @return name:pay_at type:string default:-- desc:支付时间
  607. * @return name:create_at type:string default:-- desc:订单创建时间
  608. * @return name:remark type:string default:-- desc:备注
  609. * @return name:cancel_at type:string default:-- desc:取消时间(status=9)
  610. * @return name:cancel_desc type:string default:-- desc:取消描述(status=9)
  611. * @return name:refund_type type:int default:-- desc:订单申请退款、退换货状态0未申请,1申请
  612. * @return name:source type:int default:0 desc:订单来源:0商城,1积分商城
  613. * @return name:integral type:int default:0 desc:使用多少积分
  614. * @return name:int_cash type:int default:0 desc:积分抵扣多少金额
  615. * @return name:cl_id type:int default:0 desc:使用优惠券的id
  616. * @return name:coupon_cash type:float default:0 desc:券抵扣金额
  617. */
  618. public function getMyOrderList()
  619. {
  620. $status = input('status',-1);
  621. $where=[];
  622. if($status > -1) $where['o.status'] = $status;
  623. $where['o.uid'] = $this->uid;
  624. $where['o.is_deleted'] = 0;
  625. $list = Db::table('store_order o')
  626. ->field('o.id,status,o.order_no,o.pay_state,o.create_at,pay_at,pro_info,o.price_total,o.remark,source,integral')
  627. ->where($where)
  628. ->order('o.id desc')
  629. ->limit($this->off_set,$this->page_num)
  630. ->select();
  631. /* foreach ($list as &$v)
  632. {
  633. $v['pro_info'] = json_decode($v['pro_info'],true);
  634. }*/
  635. $this->success('获取成功',$list);
  636. }
  637. /**
  638. * @title 删除订单
  639. * @desc 删除订单
  640. * @author qc
  641. * @url /api/Order/delOrder
  642. * @method POST
  643. * @header name:Authorization require:1 desc:Token
  644. * @param name:id type:int require:1 default:1 desc:订单id
  645. */
  646. public function delOrder()
  647. {
  648. $order_id = input('post.id');
  649. $order_info = Db::table('store_order')
  650. ->where(['uid'=>$this->uid,'is_deleted'=>0,'id'=>$order_id])
  651. ->find();
  652. if(empty($order_info)) $this->error('订单不存在');
  653. Db::table('store_order')->where(['id'=>$order_id])->update(['is_deleted'=>1]);
  654. $this->success('删除成功');
  655. }
  656. /**
  657. * @title 确认收货
  658. * @desc 确认收货
  659. * @author qc
  660. * @url /api/Order/confirmReceipt
  661. * @method POST
  662. * @header name:Authorization require:1 desc:Token
  663. * @param name:id type:int require:1 default:1 desc:订单id
  664. */
  665. public function confirmReceipt(){
  666. $order_info = Db::table('store_order')
  667. ->where(['uid'=>$this->uid,'id'=>input('post.id')])
  668. ->find();
  669. if(empty($order_info) || !$order_info['status'] != 2) $this->error('商品未发货');
  670. Db::table('store_order')->where(['id'=>$order_info['id']])->update(['status'=>3,'receipt_at'=>date('Y-m-d H:i:s')]);
  671. $this->success('收货成功');
  672. }
  673. /**
  674. * @title 订单商品评论
  675. * @desc 订单商品评论
  676. * @author qc
  677. * @url /api/Order/orderEvaluate
  678. * @method POST
  679. * @header name:Authorization require:1 desc:Token
  680. * @param name:order_id type:int require:1 default:-- desc:订单order_id
  681. * @param name:goods_id type:int require:1 default:-- desc:商品id
  682. * @param name:goods_no type:int require:1 default:-- desc:商品货号
  683. * @param name:goods_score type:int require:1 default:-- desc:商品评分
  684. * @param name:content type:string require:1 default:-- desc:评论内容
  685. * @param name:images type:int require:1 default:-- desc:图片(多张逗号隔开)
  686. */
  687. public function orderEvaluate()
  688. {
  689. $order_id = input('post.order_id');
  690. $goods_id = input('post.goods_id');
  691. $goods_no = input('post.goods_no');
  692. $goods_score = input('post.goods_score');
  693. $images = input('post.images');
  694. $content = input('post.content');
  695. $eva_data =[
  696. 'order_id' => $order_id,
  697. 'goods_id' => $goods_id,
  698. 'goods_no' => $goods_no,
  699. 'goods_score' => $goods_score,
  700. 'images' => $images,
  701. 'content' => $content,
  702. ];
  703. Db::table('goods_evaluate')->insert($eva_data);
  704. $order_info = Db::table('order_goods')->where(['id'=>$order_id])->find();
  705. $pro_info = json_decode($order_info['pro_info'],true);
  706. foreach ($pro_info as $pk=>$pv) {
  707. if($pv['goods_id'] == $goods_id && $pv['goods_no'] == $goods_no) {
  708. $pro_info[$pk]['is_evaluate'] = 1;
  709. }
  710. }
  711. Db::table('order_goods')->where(['id'=>$order_id])->update(['status'=>4,'pro_info'=>json_encode($pro_info)]);
  712. }
  713. /**
  714. * @title 退款部分
  715. * @desc 退款部分
  716. */
  717. public function refundPart(){}
  718. /**
  719. * @title 获取平台退款原因
  720. * @desc 获取平台退款原因
  721. * @author qc
  722. * @url /api/Order/getRefundCause
  723. * @method GET
  724. * @header name:Authorization require:1 desc:Token
  725. * @return name:id type:int default:-- desc:记录id
  726. * @return name:title type:string default:-- desc:退款原因描述
  727. */
  728. public function getRefundCause(){
  729. $list = get_refund_cause();
  730. $this->success('ok',['list'=>$list]);
  731. }
  732. /**
  733. * @title 提交订单退款
  734. * @desc 提交订单退款
  735. * @author qc
  736. * @url /api/Order/refundOrder
  737. * @method POST
  738. * @header name:Authorization require:1 desc:Token
  739. * @param name:order_id type:int require:1 default:1 desc:订单id
  740. * @param name:cause_id type:int require:1 default:1 desc:退款原因id
  741. * @param name:apply_type type:int require:1 default:1 desc:申请类型 1退款,2退货退款
  742. * @param name:apply_money type:float require:1 default:1 desc:申请退回金额
  743. * @param name:re_desc type:string require:0 default:-- desc:描述
  744. * @param name:re_images type:string require:0 default:-- desc:退款图片最多三张(多张用逗号隔开)
  745. * @return name:re_id type:int require:0 default:0 desc:成功时返回退款记录id
  746. */
  747. public function refundOrder()
  748. {
  749. $order_id = input('post.order_id');
  750. $cause_id = input('post.cause_id');
  751. $apply_type = input('post.apply_type',1);
  752. $apply_money = input('post.apply_money');
  753. $re_desc = input('post.re_desc');
  754. $re_images = input('post.re_images');
  755. $ck_refund = Db::table('order_refund')
  756. ->where(['order_id'=>$order_id,'ck_status'=>0])
  757. ->value('id');
  758. if($ck_refund) $this->error('审核中,请勿重新申请');
  759. $ref_data = [
  760. 'uid' => $this->uid,
  761. 'order_id' => $order_id,
  762. 'apply_type' => $apply_type,
  763. 'apply_money' => $apply_money,
  764. 'create_at' => date("Y-m-d H:i:s"),
  765. 'cause_id' => $cause_id,
  766. 're_desc' => $re_desc,
  767. 're_images' => $re_images,
  768. ];
  769. Db::table('order_refund')->insert($ref_data);
  770. $re_id = Db::getLastInsID();
  771. // 更新订单表退款申请状态
  772. Db::table('store_order')->where('id',$order_id)->update(['refund_state'=>1]);
  773. $this->success('ok',['re_id'=>$re_id]);
  774. }
  775. /**
  776. * @title 获取提交订单退款详情
  777. * @desc 获取提交订单退款详情
  778. * @author qc
  779. * @url /api/Order/getRefundInfo
  780. * @method GET
  781. * @header name:Authorization require:1 desc:Token
  782. * @param name:id type:int require:1 default:1 desc:退款记录id
  783. * @return name:cause_id type:int default:1 desc:退款原因id
  784. * @return name:apply_type type:int default:1 desc:申请类型 1退款,2退货退款
  785. * @return name:apply_money type:float default:1 desc:申请退回金额
  786. * @return name:create_at type:string default:1 desc:申请时间
  787. * @return name:re_desc type:string default:-- desc:描述
  788. * @return name:re_images type:string default:-- desc:退款图片
  789. * @return name:pro_info type:string default:-- desc:申请订单的商品详情
  790. * @return name:pro_info.goods_id type:int default:-- desc:商品id
  791. * @return name:pro_info.goods_no type:string default:-- desc:商品货号
  792. * @return name:pro_info.sell_money type:string default:-- desc:售价
  793. * @return name:pro_info.spec_img type:string default:-- desc:封面
  794. * @return name:pro_info.is_evaluate type:string default:-- desc:商品是否评价
  795. * @return name:goods_num type:string default:-- desc:购买的商品数量
  796. * @return name:ck_status type:int default:0 desc:审核状态(0待审核 ,1 审核通过 , 2 审核不通过),
  797. * @return name:refund_money type:float default:0 desc:审核退款金额,
  798. * @return name:refund_state type:int default:0 desc:同意退款后的退款状态(0未退款,1待退款,2已退款,3退款失败)
  799. * @return name:refund_desc type:int default:0 desc:退款描述
  800. * @return name:wl_no type:string default:0 desc:退货物流单号 ( apply_type = 2)
  801. * @return name:wl_company type:string default:0 desc:退货物流公司( apply_type = 2)
  802. */
  803. public function getRefundInfo()
  804. {
  805. $id = input('post.id');
  806. $detail = Db::table('order_refund')
  807. ->field('r.*,o.pro_info,o.goods_num')
  808. ->alias('r')
  809. ->join('store_order o','r.order_id = o.id','LEFT')
  810. ->where(['r.order_id'=>$id])
  811. ->find();
  812. $re_cause = get_refund_cause();
  813. $detail['refund_desc'] = array_column($re_cause,null,'id')[$detail['cause_id']]['title'];
  814. $this->success('ok',['refund_detail'=>$detail]);
  815. }
  816. /**
  817. * @title 完善退货物流信息
  818. * @desc 完善退货物流信息
  819. * @author qc
  820. * @url /api/Order/completeLogistics
  821. * @method POST
  822. * @header name:Authorization require:1 desc:Token
  823. * @param name:id type:int require:1 default:-- desc:退款记录id
  824. * @param name:wl_no type:string require:1 default:-- desc:物流单号
  825. * @param name:wl_company type:string require:1 default:1 desc:物流公司
  826. */
  827. public function completeLogistics()
  828. {
  829. $id = input('post.id');
  830. $wl_no = input('post.wl_no');
  831. $wl_company = input('post.wl_company');
  832. $info = $detail = Db::table('order_refund')->find($id);
  833. if($info['apply_type'] == 1) $this->error('申请类型不符合,无需物流信息');
  834. // 更新物流信息
  835. Db::table('order_refund')->where(['id'=>$id])->update(['wl_no'=>$wl_no,'wl_company'=>$wl_company]);
  836. $this->success('ok');
  837. }
  838. /**
  839. * @title 修改订单退款(退货)申请信息
  840. * @desc 修改订单退款(退货)申请信息
  841. * @author qc
  842. * @url /api/Order/modifyRefundInfo
  843. * @method POST
  844. * @header name:Authorization require:1 desc:Token
  845. * @param name:id type:int require:1 default:1 desc:需要修改的退款申请id
  846. * @param name:cause_id type:int require:1 default:1 desc:退款原因id
  847. * @param name:apply_type type:int require:1 default:1 desc:申请类型 1退款,2退货退款
  848. * @param name:apply_money type:float require:1 default:1 desc:申请退回金额
  849. * @param name:re_desc type:string default:-- desc:描述
  850. * @param name:re_images type:string default:-- desc:退款图片最多三张(多张用逗号隔开)
  851. * @param name:wl_no type:string default:-- desc:物流单号
  852. * @param name:wl_company type:string default:1 desc:物流公司
  853. */
  854. public function modifyRefundInfo()
  855. {
  856. $id = input('post.id');
  857. $detail = Db::table('order_refund')->find($id);
  858. if($detail['ck_status'] != 0) $this->error('已审核无法修改,请重新提交');
  859. $up_data = [];
  860. if(input('post.cause_id')) $up_data['cause_id'] = input('post.cause_id');
  861. if(input('post.apply_type')) $up_data['apply_type'] = input('post.apply_type');
  862. if(input('post.apply_money')) $up_data['apply_money'] = input('post.apply_money');
  863. if(input('post.re_desc')) $up_data['re_desc'] = input('post.re_desc');
  864. if(input('post.re_images')) $up_data['re_images'] = input('post.re_images');
  865. if(input('post.wl_no')) $up_data['wl_no'] = input('post.wl_no');
  866. if(input('post.wl_company')) $up_data['wl_company'] = input('post.wl_company');
  867. if(!empty($up_data)) {
  868. Db::table('order_refund')->where(['id'=>$id])->update($up_data);
  869. }
  870. $this->success('修改成功');
  871. }
  872. /**
  873. * @title 取消申请退款(退货)
  874. * @desc 取消申请退款(退货)
  875. * @author qc
  876. * @url /api/Order/cancelRefund
  877. * @method POST
  878. * @header name:Authorization require:1 desc:Token
  879. * @param name:order_id type:int require:1 default:1 desc:订单id
  880. */
  881. public function cancelRefund(){
  882. $order_id = input('post.order_id');
  883. $re_info = Db::table('order_refund')->where(['uid'=>$this->uid,'order_id'=>$order_id,'ck_status'=>0])->count();
  884. if(!$re_info) $this->error('退款记录不存在');
  885. // 删除记录
  886. Db::table('order_refund')->where(['order_id'=>$order_id,'ck_status'=>0])->delete();
  887. $ck = Db::table('order_refund')->where(['order_id'=>$order_id])->find();
  888. $stat = empty($ck) ? 0 : 2 ;
  889. Db::table('store_order')->where(['id'=>$order_id])->update(['refund_state'=>$stat]);
  890. }
  891. /**
  892. * @title 获取提交订单退款列表 ???
  893. * @desc 获取提交订单退款列表 ???
  894. */
  895. public function getRefundList()
  896. {
  897. }
  898. }