Order.php 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\model\OrderComment;
  4. use app\common\model\OrderLogisticsUrge;
  5. use app\common\model\ShoppingTrolley;
  6. use app\common\model\DeliveryAddress;
  7. use app\common\model\StoreGoods;
  8. use app\common\model\StoreGoodsItem;
  9. use app\common\model\GoodsOrder;
  10. use app\common\model\GoodsOrderItem;
  11. use app\common\model\User;
  12. use app\common\model\UserMessage;
  13. use app\common\service\ExpressService;
  14. use think\Db;
  15. use think\Exception;
  16. /**
  17. * @title 订单
  18. * @controller Order
  19. * @group base
  20. */
  21. class Order extends Base
  22. {
  23. public $int_rate = 100;
  24. public function initialize()
  25. {
  26. parent::initialize();
  27. parent::checkLogin();
  28. }
  29. /**
  30. * @title 订单确认页面(立即购买)
  31. * @desc 订单确认页面
  32. * @author qc
  33. * @url /api/Order/confirmOrderImmediately
  34. * @method GET
  35. * @header name:Authorization require:1 desc:Token
  36. * @param name:goods_id type:int require:1 default:0 desc:商品id
  37. * @param name:spec_id type:int require:1 default:0 desc:商品多规格的规格id
  38. * @param name:num type:int default:1 desc:数量
  39. * @return name:name type:string default:-- desc:商品名称
  40. * @return name:cover type:string default:-- desc:商品封面图
  41. * @return name:desc type:string default:-- desc:商品简述(副标题)
  42. * @return name:freight_type type:int default:-- desc:运费类型0固定金额,1运费模板
  43. * @return name:freight_id type:int default:-- desc:模板id(freight_type=1)
  44. * @return name:postage type:float default:-- desc:运费(freight_type=0)
  45. * @return name:total_price type:float default:-- desc:商品金额[不含运费]
  46. * @return name:freight type:float default:-- desc:运费
  47. * @return name:freight_code type:int default:1 desc:运费提示编号【1所选地址支持发货,0所选地址不支持发货】
  48. * @return name:freight_msg type:string default:-- desc:运费提示信息【freight_code=1忽略】
  49. * @return name:goods_no type:string default:-- desc:规格货号
  50. * @return name:goods_spec type:string default:-- desc:规格
  51. * @return name:sell_price type:float default:-- desc:售价
  52. * @return name:add_info type:array default:-- desc:默认收货地址(设置才有)
  53. * @return name:add_info.pro_id type:int default:-- desc:省id
  54. * @return name:add_info.city_id type:int default:-- desc:市id
  55. * @return name:add_info.county_id type:int default:-- desc:县区id
  56. * @return name:add_info.pro_name type:string default:-- desc:省名
  57. * @return name:add_info.city_name type:string default:-- desc:市名
  58. * @return name:add_info.county_name type:string default:-- desc:县区名
  59. * @return name:add_info.detail type:string default:-- desc:详细地址
  60. * @return name:add_info.phone type:string default:-- desc:联系电话
  61. * @return name:add_info.name type:string default:-- desc:联系人
  62. * @return name:freight type:float default:-- desc:运费
  63. * @return name:freight_code type:int default:1 desc:运费提示编号【1所选地址支持发货,0所选地址不支持发货】
  64. * @return name:freight_msg type:string default:-- desc:运费提示信息【freight_code=1忽略】
  65. */
  66. public function confirmOrderImmediately(){
  67. $goods_id = input('get.goods_id');
  68. $spec_id = input('get.spec_id');
  69. $num = input('get.num',1);
  70. $field = 'id,name,cover,desc,low_price,status,is_deleted,freight_type,postage,freight_id';
  71. $goods_info = StoreGoods::field($field)->where('id',$goods_id)->find()->toArray();
  72. $spec_info = StoreGoodsItem::where('id',$spec_id)->find()->toArray();
  73. $goods_info['total_price']= bcmul($spec_info['sell_price'],$num,2);
  74. $goods_info['goods_spec']= $spec_info['goods_spec'];
  75. $goods_info['goods_no']= $spec_info['goods_no'];
  76. $goods_info['sell_price']= $spec_info['sell_price'];
  77. $add_info = DeliveryAddress::where(['user_id'=>$this->user_id,'is_mr'=>1])->find();
  78. $freight = 0;
  79. if($add_info){
  80. $goods_freight = ExpressService::getGoodsExpressPrice($goods_info,$add_info->id,$num);
  81. if($goods_freight['code'] !=200){
  82. $this->is_commit = false;
  83. $this->ret_msg = $goods_freight['msg'];
  84. }
  85. if($goods_freight['code'] == 200) $freight = $goods_freight['freight'];
  86. }
  87. $this->success('ok',['goods_info'=>$goods_info,
  88. 'add_info' =>$add_info ? $add_info->toArray():null,
  89. 'freight' =>$freight,
  90. 'freight_msg' => $this->ret_msg,
  91. 'freight_code' => $this->is_commit ? 1 :0
  92. ]);
  93. }
  94. /**
  95. * @title 生成订单(立即购买)
  96. * @desc 立即购买场景
  97. * @author qc
  98. * @url /api/Order/createOrderImmediately
  99. * @method POST
  100. * @header name:Authorization require:1 desc:Token
  101. * @param name:goods_id type:int require:1 default:0 desc:商品id
  102. * @param name:spec_id type:int require:1 default:0 desc:商品多规格的规格id
  103. * @param name:num type:int default:1 desc:数量
  104. * @param name:add_id type:int default:1 desc:收货地址id
  105. * @param name:remark type:string default:1 desc:订单备注
  106. * @return name:order_id type:int default:1 desc:订单id
  107. */
  108. public function createOrderImmediately()
  109. {
  110. $goods_id = input('post.goods_id');
  111. $spec_id = input('post.spec_id');
  112. $num = input('post.num');
  113. $add_id = input('post.add_id');
  114. $remark = input('post.remark');
  115. if(!$goods_id || !$spec_id) $this->error('请选择商品');
  116. if($num <=0 ) $this->error('数量有误');
  117. if(!$add_id ) $this->error('请选择收货地址');
  118. Db::startTrans();
  119. try {
  120. $add_info = DeliveryAddress::find($add_id)->toArray();
  121. $order_insert = [
  122. 'user_id' => $this->user_id,
  123. 'order_no' => get_order_sn(),
  124. 'goods_num' => $num,
  125. 'pro_name' => $add_info['pro_name'],
  126. 'city_name' => $add_info['city_name'],
  127. 'county_name' => $add_info['county_name'],
  128. 'street_name' => $add_info['street_name'],
  129. 'user_name' => $add_info['name'],
  130. 'add_detail' => $add_info['detail'],
  131. 'phone' => $add_info['phone'],
  132. 'remark' => $remark,
  133. ];
  134. $goods_info = StoreGoods::with(['itemList'=>function($query)use($spec_id){
  135. return $query->where('id',$spec_id)->where('is_deleted',0);
  136. }])->where('id',$goods_id)->where('is_deleted',0)->where('status',1)->find();
  137. if(!$goods_info) throw new Exception('商品已下架');
  138. $goods_info = $goods_info->toArray();
  139. if(empty($goods_info['item_list'])) throw new Exception('该规格已下架');
  140. if($goods_info['item_list'][0]['stock'] < $num) throw new Exception('库存不足');
  141. $order_insert['original_price'] = bcmul($num,$goods_info['item_list'][0]['original_price'],2);// 原价
  142. $true_cost = $goods_info['item_list'][0]['sell_price'];//实际售价
  143. $spec_info = $goods_info['item_list'][0];
  144. $price_goods = bcmul($num,$true_cost,2); // 需要支付商品价格
  145. // 获取运费信息
  146. $exp_data = ExpressService::getGoodsExpressPrice($goods_info,$add_info,$num);
  147. if($exp_data['code'] != 200 ) throw new Exception($exp_data['msg']);
  148. $price_express = $exp_data['freight']; // 商品运费
  149. //订单金额 = 商品金额 + 运费
  150. $order_money = bcadd($price_goods,$price_express ,2);
  151. if($order_money < 0) $this->exception('订单金额有误');
  152. $order_insert['price_total'] = $order_money;
  153. $order_insert['price_goods'] = $price_goods;
  154. $order_insert['price_express'] = $price_express;
  155. $order_info = GoodsOrder::create($order_insert);
  156. $order_item = [
  157. 'user_id' => $this->user_id,
  158. 'order_id' => $order_info->id,
  159. 'goods_id' => $goods_id,
  160. 'goods_no' => $spec_info['goods_no'],
  161. 'goods_spec' => $spec_info['goods_spec'],
  162. 'goods_name' => $goods_info['name'],
  163. 'spec_title' => $spec_info['spec_title'],
  164. 'spec_id' => $spec_info['id'],
  165. 'cover' => $goods_info['cover'],
  166. 'original_price' => $spec_info['original_price'],
  167. 'sell_price' => $true_cost,
  168. 'pay_price' => $order_money,
  169. 'num' => $num,
  170. ];
  171. GoodsOrderItem::create($order_item);
  172. StoreGoods::where('id',$goods_id)->setDec('stock',$num);
  173. StoreGoodsItem::where('id',$spec_id)->setDec('stock',$num);
  174. Db::commit();
  175. }catch (\Exception $e){
  176. $this->is_commit = false;
  177. $this->ret_msg = $e->getMessage();
  178. Db::rollback();
  179. }
  180. $this->is_commit ? $this->success('添加成功',['order_id'=>$order_info->id]):$this->error($this->ret_msg);
  181. }
  182. /**
  183. * @title 生成订单(购物车)
  184. * @desc 购物车场景
  185. * @author qc
  186. * @url /api/Order/createOrderByTrolley
  187. * @method POST
  188. * @header name:Authorization require:1 desc:Token
  189. * @param name:ids type:int require:1 default:0 desc:购物车记录id
  190. * @param name:add_id type:int default:1 desc:收货地址id
  191. * @param name:remark type:string default:1 desc:订单备注
  192. * @return name:order_id type:int default:1 desc:订单id
  193. */
  194. public function createOrderByTrolley()
  195. {
  196. $ids = input('post.ids');
  197. $add_id = input('post.add_id');
  198. if(!$ids) $this->error('请选择商品');
  199. if(!$add_id ) $this->error('请选择收货地址');
  200. $ret_data = ['order_id'=>0];
  201. Db::startTrans();
  202. try{
  203. $add_info = DeliveryAddress::where('id',$add_id)->find()->toArray();
  204. $trolley_list = ShoppingTrolley::with(['goodsSpec','goodsInfo'])->where('id','in',$ids)->select()->toArray();
  205. if(empty($trolley_list)) $this->exception('购物车记录有误');
  206. // 计算运费
  207. $price_express = 0;// 总运费
  208. $goods_list = ShoppingTrolley::where('id','in',$ids)->field('goods_id,sum(num) as total_num')->group('goods_id')->select()->toArray();
  209. foreach ($goods_list as $v){
  210. $goods_info = StoreGoods::field('name,freight_type,freight_id,postage')->where('id',$v['goods_id'])->find()->toArray();
  211. $freight_data = ExpressService::getGoodsExpressPrice($goods_info,$add_info,$v['total_num']);
  212. if($freight_data['code'] != 200){
  213. $this->exception($goods_info['name'].$freight_data['msg']);
  214. break;
  215. }
  216. $price_express += $freight_data['freight'];
  217. }
  218. // 计算运费 end
  219. $price_goods = 0; // 商品总金额
  220. $original_total = 0; // 商品总原价
  221. $total_num = 0;// 商品总数量
  222. $order_item = [];// 订单列表
  223. foreach ($trolley_list as $trolley)
  224. {
  225. $price_goods += $trolley['num'] * $trolley['goods_spec']['sell_price'];
  226. $original_total += $trolley['num'] * $trolley['goods_spec']['original_price'];
  227. $total_num +=$trolley['num'];
  228. $order_item[] = [
  229. 'user_id' => $this->user_id,
  230. 'goods_id' => $trolley['goods_id'],
  231. 'goods_no' => $trolley['goods_spec']['goods_no'],
  232. 'goods_name' => $trolley['goods_info']['name'],
  233. 'goods_spec' => $trolley['goods_spec']['goods_spec'],
  234. 'spec_title' => $trolley['goods_spec']['spec_title'],
  235. 'spec_id' => $trolley['spec_id'],
  236. 'cover' => $trolley['goods_info']['cover'],
  237. 'original_price' => $trolley['goods_spec']['original_price'],
  238. 'sell_price' => $trolley['goods_spec']['sell_price'],
  239. 'num' => $trolley['num'],
  240. 'trolley_id' => $trolley['id'],
  241. ];
  242. }
  243. $order_insert = [
  244. 'user_id' => $this->user_id,
  245. 'order_no' => get_order_sn(),
  246. 'goods_num' => $total_num,
  247. 'pro_name' => $add_info['pro_name'],
  248. 'city_name' => $add_info['city_name'],
  249. 'county_name' => $add_info['county_name'],
  250. 'user_name' => $add_info['name'],
  251. 'add_detail' => $add_info['detail'],
  252. 'phone' => $add_info['phone'],
  253. ];
  254. $price_total = bcadd($price_goods ,$price_express,2);
  255. $order_insert['price_total'] = $price_total;
  256. $order_insert['price_goods'] = $price_goods ;
  257. $order_insert['original_total'] = $original_total ;
  258. $order_insert['price_express'] = $price_express ;
  259. $order_info = GoodsOrder::create($order_insert);// 生成订单
  260. array_walk($order_item,function (&$v,$k)use ($order_info){
  261. $v['order_id'] = $order_info->id;
  262. });
  263. (new GoodsOrderItem())->insertAll($order_item);// 生成订单商品详情
  264. ShoppingTrolley::where('id','in',$ids)->delete();// 删除购物车
  265. $ret_data['order_id'] = $order_info->id;
  266. Db::commit();
  267. }catch (\Exception $e){
  268. $this->ret_msg = $e->getMessage();
  269. $this->is_commit = false;
  270. Db::rollback();
  271. }
  272. $this->transReturn($ret_data);
  273. }
  274. /**
  275. * @title 订单支付
  276. * @desc 订单支付
  277. * @author qc
  278. * @url /api/Order/payOrder
  279. * @method POST
  280. * @header name:Authorization require:1 desc:Token
  281. * @param name:order_id type:int require:1 default:0 desc:订单id
  282. * @param name:pay_type type:int require:1 default:0 desc:支付方式(1.h5微信,2.h5支付宝,3移动支付(微信),4移动支付(支付宝),5.h5微信内支付)
  283. * @return name:config type:array default:0 desc:小程序支付配置
  284. * @return name:config.appId type:string default:-- desc:公众账号ID(小程序支付)
  285. * @return name:config.signType type:string default:-- desc:签名类型(小程序支付)
  286. * @return name:config.paySign type:string default:-- desc:签名(小程序支付)
  287. * @return name:config.nonceStr type:string default:-- desc:随机字符串(小程序支付&&APP支付)
  288. * @return name:config.timestamp type:string default:-- desc:时间戳小程序支付&&APP支付)
  289. * @return name:config.partnerid type:string default:-- desc:商户号(App支付)
  290. * @return name:config.prepayid type:string default:-- desc:唯一支付号(App支付)
  291. * @return name:config.package type:string default:-- desc:package(App支付)
  292. * @return name:config.sign type:string default:-- desc:签名(App支付)
  293. * @return name:code_url type:string default:-- desc:付款码url
  294. */
  295. public function payOrder()
  296. {
  297. $order_id = input('post.order_id');
  298. $pay_type = input('post.pay_type');
  299. $order_info = GoodsOrder::with('orderItem')->where('id',$order_id)->find()->toArray();
  300. if($order_info['status'] != 0) $this->error('订单状态错误');
  301. if($order_info['cancel_state'] != 0 || $order_info['is_deleted'] != 0) $this->error('订单异常');
  302. if($order_info['price_total'] <= 0) $this->error('订单金额错误');
  303. $pay_no = $order_info['pay_no'] ? $order_info['pay_no'] : get_order_sn();// 支付单号
  304. if(!$order_info['pay_no']) GoodsOrder::where('id',$order_id)->update(['pay_no'=>$pay_no]);
  305. $user_info = User::with('wallet')->where('id',$this->user_id)->find()->toArray();
  306. if(in_array($order_info['pay_type'],[1,3,5]) && in_array($pay_type,[1,3,5]) && $pay_type != $order_info['pay_type'] )$this->error('微信支付冲突,请选择支付宝支付');
  307. $ret_data = ['pay_status'=>0,'config'=>[],'code_url'=>''];
  308. Db::startTrans();
  309. GoodsOrder::where('id',$order_id)->update(['pay_type'=>$pay_type]);
  310. try {
  311. switch ($pay_type){
  312. case 1://微信
  313. $notify_url = $this->request->root(true) . '/api/we_chat_pay/goodsOrderNotify';
  314. $pay_config = WeChatPay::wxPay('订单支付',$pay_no,$order_info['price_total'],$notify_url,'MWEB');
  315. if($pay_config['code'] != 200) $this->exception($pay_config['msg']);
  316. $pay_config['config']['mch_id'] = config('app.wx_pay')['mch_id'];
  317. $pay_config['config']['pay_no'] = $pay_no;
  318. $pay_config['config']['notify_url'] = $notify_url;
  319. $pay_config['config']['mweb_url'] = $pay_config['mweb_url'];
  320. $pay_config['config']['total_fee'] = $order_info['price_total'] * 100;
  321. $ret_data['config'] = $pay_config['config'];
  322. break;
  323. case 2:
  324. $notify_url = $this->request->root(true) . '/api/Alipay/goodsOrderNotify';
  325. $return_url ='https://'.$_SERVER['HTTP_HOST']."/dist/#/my";
  326. $config = Alipay::ali_pay_pc('订单支付',$pay_no,$order_info['price_total'],$notify_url,$return_url);
  327. $ret_data['config']['ali_url'] = $config;
  328. $ret_data['ali_url'] = $config;
  329. break;
  330. case 3: //移动支付(微信)
  331. $notify_url = $this->request->root(true) . '/api/we_chat_pay/goodsOrderNotify';
  332. $pay_config = WeChatPay::wxPay('订单支付',$pay_no,$order_info['price_total'],$notify_url,'APP');
  333. if($pay_config['code'] != 200) $this->exception($pay_config['msg']);
  334. $ret_data['config'] = $pay_config['config'];
  335. break;
  336. case 4://移动支付(支付宝)
  337. $notify_url = $this->request->root(true) . '/api/Alipay/goodsOrderNotify';
  338. $config = Alipay::ali_pay('订单支付',$pay_no,$order_info['price_total'],$notify_url);
  339. $ret_data['config']['ali_url'] = $config;
  340. $ret_data['ali_url'] = $config;
  341. break;
  342. case 5 :
  343. if(!$user_info['openid']) $this->exception('请绑定openid');
  344. $notify_url = $this->request->root(true) . '/api/we_chat_pay/goodsOrderNotify';
  345. $pay_config = WeChatPay::wxPay('订单支付',$pay_no,$order_info['price_total'],$notify_url,'JSAPI',$user_info['openid']);
  346. if($pay_config['code'] != 200) $this->exception($pay_config['msg']);
  347. $ret_data['config'] = $pay_config['config'];
  348. break;
  349. }
  350. Db::commit();
  351. }catch (\Exception $e){
  352. $this->is_commit = false;
  353. $this->ret_msg = $e->getMessage();
  354. Db::rollback();
  355. }
  356. $this->transReturn($ret_data);
  357. }
  358. /**
  359. * @title 获取订单列表
  360. * @desc 订单优惠:int_cash + coupon_cash
  361. * @author qc
  362. * @method GET
  363. * @url /api/Order/getOrderList
  364. * @header name:Authorization require:1 desc:Token
  365. * @param name:page type:int default:1 desc:页数
  366. * @param name:page_num type:int default:20 desc:每页数
  367. * @param name:status type:int default:-1 desc:订单状态(0待支付,1已支付(待发货),2已发货(待收货),3已收货(待评论)4已完成,8已退款,9取消)
  368. * @param name:pay_state type:int default:-1 desc:支付状态(-1全部,0未支付,1已支付)
  369. * @param name:cancel_state type:int default:-1 desc:取消状态(-1全部,0未取消,1已取消)
  370. * @param name:apply_refund type:int default:-1 desc:申请退款状态(-1全部,0未申请||已取消,1已申请)
  371. * @return name:id type:int default:-- desc:订单id
  372. * @return name:order_no type:string default:-- desc:订单号
  373. * @return name:price_total type:float default:-- desc:待支付金额(所以优惠完价格+运费)
  374. * @return name:price_goods type:float default:-- desc:商品金额(用售价计算)
  375. * @return name:price_express type:float default:-- desc:运费金额
  376. * @return name:original_total type:float default:-- desc:总原价(下划线)
  377. * @return name:pay_state type:int default:-- desc:支付状态(0未支付1已支付)
  378. * @return name:pay_type type:int default:-- desc:支付方式(1.h5微信,2.h5支付宝,3移动支付(微信),4移动支付(支付宝),5.h5微信内支付)
  379. * @return name:pay_no type:string default:-- desc:支付号
  380. * @return name:pay_at type:string default:-- desc:支付时间
  381. * @return name:cancel_state type:int default:-- desc:取消状态(0未取消1已取消)
  382. * @return name:cancel_at type:string default:-- desc:取消时间
  383. * @return name:cancel_desc type:string default:-- desc:取消原因
  384. * @return name:cancel_desc type:string default:-- desc:取消原因
  385. * @return name:refund_state type:int default:-- desc:退款状态(0未申请1待审核,2审核通过,3审核拒绝)
  386. * @return name:express_state type:int default:-- desc:发货状态(0未发货,1已发货,2已签收)
  387. * @return name:express_company_title type:string default:-- desc:发货快递公司名称
  388. * @return name:express_send_no type:string default:-- desc:物流单号
  389. * @return name:express_send_at type:string default:-- desc:发货时间
  390. * @return name:status type:int default:-- desc:订单状态(0待支付,1已支付(待发货),2已发货(待收货),3已收货(待评论)4已完成,8已退款,9取消)
  391. * @return name:create_at type:string default:-- desc:下单时间
  392. * @return name:integral type:string default:-- desc:使用积分数量
  393. * @return name:int_cash type:float default:-- desc:使用积分抵扣金额
  394. * @return name:cl_ids type:string default:-- desc:使用优惠券id串
  395. * @return name:coupon_cash type:string default:-- desc:使用优惠券抵扣金额
  396. * @return name:blance type:string default:-- desc:使用余额支付金额
  397. * @return name:redu_money type:float default:-- desc:订单满减金额
  398. * @return name:remark type:string default:-- desc:订单备注
  399. * @return name:goods_num type:int default:-- desc:订单商品总数量
  400. * @return name:pro_name type:string default:-- desc:省名称(收货地址)
  401. * @return name:city_name type:string default:-- desc:市名称(收货地址)
  402. * @return name:county_name type:string default:-- desc:县区名称(收货地址)
  403. * @return name:street_name type:string default:-- desc:街道名称(收货地址)
  404. * @return name:add_detail type:string default:-- desc:详细地址(收货地址)
  405. * @return name:user_name type:string default:-- desc:收货人
  406. * @return name:phone type:string default:-- desc:收货人联系电话
  407. * @return name:act_type type:int default:-- desc:活动类型0无1秒杀2拼团
  408. * @return name:act_id type:int default:-- desc:活动id
  409. * @return name:share_user type:int default:-- desc:分享人id
  410. * @return name:order_item type:array default:-- desc:订单商品列表
  411. * @return name:order_item.name type:float default:-- desc:商品名
  412. * @return name:order_item.cover type:float default:-- desc:商品图
  413. * @return name:order_item.sell_price type:float default:-- desc:购买价格
  414. * @return name:order_item.goods_spec type:float default:-- desc:规格
  415. * @return name:order_item.num type:int default:-- desc:数量
  416. */
  417. public function getOrderList()
  418. {
  419. $status = input('get.status',-1);
  420. $pay_state = input('get.pay_state',-1);
  421. $cancel_state = input('get.cancel_state',-1);
  422. $refund_state = input('get.apply_refund',-1);
  423. $where = [];
  424. $where[] = ['user_id','=',$this->user_id];
  425. if($status > -1) $where[] = ['status','=',$status];
  426. if($pay_state > -1) $where[] = ['pay_state','=',$pay_state];
  427. if($cancel_state > -1) $where[] = ['cancel_state','=',$cancel_state];
  428. if($refund_state == 0) $where[] = ['refund_state','=',$refund_state];
  429. if($refund_state == 1) $where[] = ['refund_state','in','1,2,3,4'];
  430. $list = GoodsOrder::with(['orderItem'])->where($where)->order('id desc ')
  431. ->limit($this->off_set,$this->page_num)
  432. ->select()->toArray();
  433. foreach ($list as &$info) {
  434. foreach ($info['order_item'] as &$v) {
  435. $v['goods_spec'] = str_replace(['::',';;'],[':',';'],$v['goods_spec']);
  436. }
  437. }
  438. $this->success('',['list'=>$list]);
  439. }
  440. /**
  441. * @title 获取订单详情
  442. * @desc 获取订单详情
  443. * @author qc
  444. * @method GET
  445. * @url /api/Order/getOrderDetail
  446. * @header name:Authorization require:1 desc:Token
  447. * @param name:order_id type:int default:-- desc:订单id
  448. * @return name:id type:int default:-- desc:订单id
  449. * @return name:order_no type:string default:-- desc:订单号
  450. * @return name:price_total type:float default:-- desc:待支付金额(商品价格+运费)
  451. * @return name:price_goods type:float default:-- desc:商品金额
  452. * @return name:price_express type:float default:-- desc:运费金额
  453. * @return name:original_total type:float default:-- desc:总原价(下划线)
  454. * @return name:original_total type:float default:-- desc:总原价(下划线)
  455. * @return name:pay_state type:int default:-- desc:支付状态(0未支付1已支付)
  456. * @return name:pay_type type:int default:-- desc:支付方式(1.h5微信,2.h5支付宝,3移动支付(微信),4移动支付(支付宝),5.h5微信内支付)
  457. * @return name:pay_no type:string default:-- desc:支付号
  458. * @return name:pay_at type:string default:-- desc:支付时间
  459. * @return name:cancel_state type:int default:-- desc:取消状态(0未取消1已取消)
  460. * @return name:cancel_at type:string default:-- desc:取消时间
  461. * @return name:cancel_desc type:string default:-- desc:取消原因
  462. * @return name:refund_state type:int default:-- desc:退款状态(0未申请1待审核,2审核拒绝,3审核通过)
  463. * @return name:express_state type:int default:-- desc:发货状态(0未发货,1已发货,2已签收)
  464. * @return name:express_company_title type:string default:-- desc:发货快递公司名称
  465. * @return name:express_send_no type:string default:-- desc:物流单号
  466. * @return name:express_send_at type:string default:-- desc:发货时间
  467. * @return name:status type:int default:-- desc:订单状态(0待支付,1已支付(待发货),2已发货(待收货),3已收货(待评论)4已完成,8已退款,9取消)
  468. * @return name:create_at type:string default:-- desc:下单时间
  469. * @return name:blance type:string default:-- desc:使用余额支付金额(余额抵扣)
  470. * @return name:remark type:string default:-- desc:订单备注
  471. * @return name:goods_num type:int default:-- desc:订单商品总数量
  472. * @return name:pro_name type:string default:-- desc:省名称(收货地址)
  473. * @return name:city_name type:string default:-- desc:市名称(收货地址)
  474. * @return name:county_name type:string default:-- desc:县区名称(收货地址)
  475. * @return name:street_name type:string default:-- desc:街道名称(收货地址)
  476. * @return name:add_detail type:string default:-- desc:详细地址(收货地址)
  477. * @return name:user_name type:string default:-- desc:收货人
  478. * @return name:phone type:string default:-- desc:收货人联系电话
  479. * @return name:order_item type:array default:-- desc:订单商品列表(按商品id分组)
  480. * @return name:order_item.name type:float default:-- desc:商品名
  481. * @return name:order_item.cover type:float default:-- desc:商品图
  482. * @return name:order_item.sell_price type:float default:-- desc:购买价格
  483. * @return name:order_item.goods_spec type:float default:-- desc:规格
  484. * @return name:order_item.num type:int default:-- desc:数量
  485. */
  486. public function getOrderDetail()
  487. {
  488. $order_id = input('get.order_id');
  489. $detail = GoodsOrder::where('id',$order_id)->find()->toArray();
  490. $detail['order_item'] = (new GoodsOrderItem())->getOrderItem($order_id);
  491. foreach ($detail['order_item'] as &$v) {
  492. $v['goods_spec'] = str_replace(['::',';;'],[':',';'],$v['goods_spec']);
  493. }
  494. $this->success('ok',['detail'=>$detail]);
  495. }
  496. /**
  497. * @title 计算商品运费(一个商品id)
  498. * @desc 计算商品运费(一个商品id)
  499. * @author qc
  500. * @url /api/Order/getGoodsFreight
  501. * @method GET
  502. * @header name:Authorization require:1 desc:Token
  503. * @param name:goods_id type:int require:1 default:0 desc:商品id
  504. * @param name:num type:int require:1 default:0 desc:商品数量
  505. * @param name:add_id type:int require:1 default:0 desc:收货地址id
  506. * @return name:freight type:float require:0 default:0 desc运费金额
  507. */
  508. public function getGoodsFreight()
  509. {
  510. $goods_id = input('get.goods_id');
  511. $num = input('get.num');
  512. $add_id = input('get.add_id');
  513. $goods_info = StoreGoods::where('id',$goods_id)->find()->toArray();
  514. $add_info = DeliveryAddress::where('id',$add_id)->find()->toArray();
  515. $freight_data = ExpressService::getGoodsExpressPrice($goods_info,$add_info,$num);
  516. if($freight_data['code'] != 200 ) $this->error($freight_data['msg']);
  517. $this->success('ok',['freight'=>$freight_data['freight']]);
  518. }
  519. /**
  520. * @title 计算购物车商品运费
  521. * @desc 计算购物车商品运费
  522. * @author qc
  523. * @url /api/Order/getTrolleyFreight
  524. * @method GET
  525. * @header name:Authorization require:1 desc:Token
  526. * @param name:ids type:int require:1 default:0 desc:购物车商品id串
  527. * @param name:add_id type:int require:1 default:0 desc:收货地址id
  528. * @return name:freight type:float require:0 default:0 desc运费金额
  529. */
  530. public function getTrolleyFreight()
  531. {
  532. $trolley_ids = input('get.ids');
  533. $add_id = input('get.add_id');
  534. $goods_list = ShoppingTrolley::where('id','in',$trolley_ids)
  535. ->field('goods_id,sum(num) as total_num')
  536. ->group('goods_id')
  537. ->select()->toArray();
  538. $total_price = 0;
  539. $add_info = DeliveryAddress::where('id',$add_id)->find()->toArray();
  540. foreach ($goods_list as $v){
  541. $goods_info = StoreGoods::field('name,freight_type,freight_id,postage')->where('id',$v['goods_id'])->find()->toArray();
  542. $freight_data = ExpressService::getGoodsExpressPrice($goods_info,$add_info,$v['total_num']);
  543. if($freight_data['code'] != 200){
  544. $this->error($goods_info['name'].$freight_data['msg']);
  545. break;
  546. }
  547. $total_price += $freight_data['freight'];
  548. }
  549. $this->success('ok',['freight'=>$total_price]);
  550. }
  551. /**
  552. * @title 取消订单
  553. * @desc 取消订单
  554. * @author qc
  555. * @url /api/Order/cancelOrder
  556. * @method POST
  557. * @header name:Authorization require:1 desc:Token
  558. * @param name:order_id type:int require:1 default:0 desc:订单id
  559. */
  560. public function cancelOrder()
  561. {
  562. $order_id = input('post.order_id');
  563. Db::startTrans();
  564. try {
  565. $detail = GoodsOrder::with('orderItem')->where('id',$order_id)->find()->toArray();
  566. if($detail['status'] != 0) $this->exception('订单状态有误');
  567. // 取消订单状态
  568. GoodsOrder::update(['status'=>9],['id'=>$order_id]);
  569. // 订单处理
  570. foreach ($detail['order_item'] as $item_info) {
  571. // 更改订单详情状态
  572. GoodsOrderItem::update(['status'=>9],['id'=>$item_info['id']]);
  573. // 商品规格库存返回
  574. StoreGoodsItem::where('id',$item_info['spec_id'])->setInc('stock',$item_info['num']);
  575. // 商品总库存增加
  576. StoreGoods::where('id',$item_info['goods_id'])->setInc('stock',$item_info['num']);
  577. }
  578. Db::commit();
  579. }catch (\Exception $e){
  580. $this->ret_msg = $e->getMessage();
  581. $this->is_commit = false;
  582. Db::rollback();
  583. }
  584. $this->is_commit ? $this->success('取消成功') : $this->error($this->ret_msg);
  585. }
  586. /**
  587. * @title 删除订单
  588. * @desc 删除订单
  589. * @author qc
  590. * @url /api/Order/deleteOrder
  591. * @method POST
  592. * @header name:Authorization require:1 desc:Token
  593. * @param name:order_id type:int require:1 default:0 desc:订单id
  594. */
  595. public function deleteOrder()
  596. {
  597. $order_id = input('post.order_id');
  598. $detail = GoodsOrder::with('orderItem')->where('id',$order_id)->find()->toArray();
  599. if($detail['status'] == 0) $this->error('请先取消订单');
  600. GoodsOrder::update(['is_deleted'=>1],['id'=>$order_id]);
  601. $this->success('删除成功');
  602. }
  603. /**
  604. * @title 更换订单收货地址
  605. * @desc 更换订单收货地址(仅待支付订单可以修改地址)
  606. * @author qc
  607. * @url /api/Order/changeOrderDelivery
  608. * @method POST
  609. * @header name:Authorization require:1 desc:Token
  610. * @param name:order_id type:int require:1 default:0 desc:订单id
  611. * @param name:add_id type:int require:1 default:0 desc:收货地址id
  612. */
  613. public function changeOrderDelivery()
  614. {
  615. $order_id = input('post.order_id');
  616. $add_id = input('post.add_id');
  617. $detail = GoodsOrder::where('id',$order_id)->find()->toArray();
  618. if($detail['status'] != 0) $this->error('操作错误');
  619. $add_info = DeliveryAddress::where('id',$add_id)->find()->toArray();
  620. $order_update =[
  621. 'pro_name' => $add_info['pro_name'],
  622. 'city_name' => $add_info['city_name'],
  623. 'county_name' => $add_info['county_name'],
  624. 'street_name' => $add_info['street_name'],
  625. 'add_detail' => $add_info['detail'],
  626. 'user_name' => $add_info['name'],
  627. 'phone' => $add_info['phone'],
  628. ];
  629. GoodsOrder::update($order_update,['id'=>$order_id]);
  630. $this->success('修改成功');
  631. }
  632. /**
  633. * @title 确认收货
  634. * @desc 确认收货
  635. * @author qc
  636. * @url /api/Order/confirmReceipt
  637. * @method POST
  638. * @header name:Authorization require:1 desc:Token
  639. * @param name:order_id type:int require:1 default:0 desc:订单id
  640. */
  641. public function confirmReceipt()
  642. {
  643. $order_id = input('post.order_id');
  644. $detail = GoodsOrder::with('orderItem')->where('id',$order_id)->find()->toArray();
  645. if($detail['status'] == 0) $this->error('订单未支付');
  646. if($detail['status'] == 1) $this->error('订单未发货');
  647. if($detail['status'] == 3) $this->error('订单已收货');
  648. GoodsOrder::update(['status'=>3,'express_state'=>2],['id'=>$order_id]);
  649. GoodsOrderItem::update(['status'=>3,'express_state'=>2],['order_id'=>$order_id]);
  650. UserMessage::create(['user_id'=>$this->user_id,'type_id'=>3,'relation_id'=>$order_id,'content'=>'订单收货成功']);
  651. $this->success('已确认收货');
  652. }
  653. /**
  654. * @title 订单评价
  655. * @desc 订单评价
  656. * @author qc
  657. * @url /api/Order/orderComment
  658. * @method POST
  659. * @header name:Authorization require:1 desc:Token
  660. * @param name:item_id type:int require:1 default:0 desc:订单item表id
  661. * @param name:content type:string require:1 default:0 desc:评论内容
  662. * @param name:images type:string default:0 desc:图片
  663. * @param name:video type:string default:0 desc:视频
  664. * @param name:goods_core type:int default:0 desc:商品评分
  665. * @param name:wl_core type:int default:0 desc:物流评分
  666. * @param name:serve_core type:int default:0 desc:服务评分
  667. */
  668. public function orderComment()
  669. {
  670. $item_id = input('post.item_id','');
  671. $content = input('post.content','');
  672. $images = input('post.images','');
  673. $video = input('post.video','');
  674. $goods_core = input('post.goods_core','');
  675. $wl_core = input('post.wl_core','');
  676. $serve_core = input('post.serve_core','');
  677. $item = GoodsOrderItem::get($item_id);
  678. if(!$item) $this->error('订单不存在');
  679. $order_info = GoodsOrder::where('id',$item->order_id)->find();
  680. if($order_info->status < 3) $this->error('请先确认收货');
  681. GoodsOrderItem::where('id',$item->id)->update(['status'=>4]);
  682. GoodsOrder::where('id',$item->order_id)->update(['status'=>4]);
  683. $data = [
  684. 'user_id' => $this->user_id,
  685. 'order_id' =>$item->order_id,
  686. 'goods_id' =>$item->goods_id,
  687. 'spec_id' =>$item->spec_id,
  688. 'content' =>$content,
  689. 'images' =>$images,
  690. 'video' =>$video,
  691. 'goods_core' =>$goods_core,
  692. 'wl_core' =>$wl_core,
  693. 'serve_core' =>$serve_core,
  694. ];
  695. OrderComment::create($data);
  696. $this->success('评论成功');
  697. }
  698. /**
  699. * @title 以下接口为二期需求
  700. * @desc 以下接口为二期需求
  701. * @author qc
  702. * @url /api/Order/secondPhase
  703. * @method
  704. * @return name:1 type:string default:-- desc:以下接口为二期需求
  705. */
  706. public function secondPhase(){}
  707. /**
  708. * @title 获取物流详情
  709. * @desc 获取物流详情
  710. * @author qc
  711. * @url /api/Order/deliveryDetails
  712. * @method GET
  713. * @header name:Authorization require:1 desc:Token
  714. * @param name:order_id type:string require:1 default:-- desc:订单id
  715. * @return name:number type:string default:-- desc:单号
  716. * @return name:type type:string default:-- desc:快递类型
  717. * @return name:list type:array default:-- desc:数据列表
  718. * @return name:list.time type:string default:-- desc:时间
  719. * @return name:list.status type:string default:-- desc:内容
  720. * @return name:deliverystatus type:int default:-- desc:0:快递收件(揽件)1.在途中2.正在派件3.已签收4.派送失败5.疑难件6.退件签收
  721. * @return name:issign type:int default:-- desc:是否签收(1.是否签收)
  722. * @return name:expName type:string default:-- desc:快递公司名称
  723. * @return name:expSite type:string default:-- desc:快递公司官网
  724. * @return name:expPhone type:string default:-- desc:快递公司电话
  725. * @return name:courier type:string default:-- desc:快递员 或 快递站(没有则为空)
  726. * @return name:courierPhone type:string default:-- desc:快递员电话 (没有则为空)
  727. * @return name:updateTime type:string default:-- desc:快递轨迹信息最新时间
  728. * @return name:takeTime type:string default:-- desc:发货到收货消耗时长 (截止最新轨迹)
  729. * @return name:logo type:string default:-- desc:快递公司LOGO
  730. */
  731. public function deliveryDetails(){
  732. $send_no = GoodsOrder::where('id',input('get.order_id'))->value('express_send_no');
  733. if(!$send_no) $this->error('订单没有发货');
  734. $data = get_delivery($send_no);
  735. $this->success('ok',$data);
  736. }
  737. /**
  738. * @title 订单催发
  739. * @desc 订单催发
  740. * @author qc
  741. * @url /api/Order/orderUrge
  742. * @method POST
  743. * @header name:Authorization require:1 desc:Token
  744. * @param name:order_id type:string require:1 default:-- desc:订单id
  745. */
  746. public function orderUrge()
  747. {
  748. $order_id = input('post.order_id');
  749. $order_info = GoodsOrder::where('id',$order_id)->find();
  750. if(!$order_info ) $this->error('订单错误');
  751. if(!$order_info->pay_state != 1 ) $this->error('订单未支付');
  752. if(!$order_info->express_send_no != '' ) $this->error('订单已发货');
  753. $urge_ret = ExpressService::orderUrge($order_id,$this->user_id);
  754. $urge_ret['code'] == 200 ? $this->success($urge_ret['msg']) : $this->error($urge_ret['msg']);
  755. }
  756. /**
  757. * @title 获取订单催发记录
  758. * @desc 获取订单催发记录
  759. * @author qc
  760. * @url /api/Order/getUrgeList
  761. * @method GET
  762. * @header name:Authorization require:1 desc:Token
  763. * @param name:order_id type:string require:1 default:-- desc:订单id
  764. */
  765. public function getUrgeList()
  766. {
  767. $order_id = input('get.order_id');
  768. $list = OrderLogisticsUrge::where(['order_id'=>$order_id,'table_name'=>'dd_store_order'])->order('id desc')->select()->toArray();
  769. $this->success('ok',['list'=>$list]);
  770. }
  771. }