Order.php 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\model\BillApply;
  4. use app\common\model\OrderComment;
  5. use app\common\model\OrderLogisticsUrge;
  6. use app\common\model\OrderRefundCase;
  7. use app\common\model\ShoppingTrolley;
  8. use app\common\model\DeliveryAddress;
  9. use app\common\model\StoreGoods;
  10. use app\common\model\StoreGoodsItem;
  11. use app\common\model\GoodsOrder;
  12. use app\common\model\GoodsOrderItem;
  13. use app\common\model\StoreOrderRefund;
  14. use app\common\model\User;
  15. use app\common\model\UserMessage;
  16. use app\common\service\ExpressService;
  17. use app\common\service\UserSynth;
  18. use library\tools\Data;
  19. use think\Db;
  20. use think\Exception;
  21. /**
  22. * @title 订单
  23. * @controller Order
  24. * @group base
  25. */
  26. class Order extends Base
  27. {
  28. public $int_rate = 100;
  29. // 需要登录的
  30. protected $need_login = [
  31. 'createOrderImmediately',
  32. 'createOrderByTrolley',
  33. 'payOrder',
  34. 'getOrderList',
  35. 'getOrderDetail',
  36. 'getTrolleyFreight',
  37. 'cancelOrder',
  38. 'deleteOrder',
  39. 'changeOrderDelivery',
  40. 'confirmReceipt',
  41. 'orderUrge',
  42. 'getUrgeList',
  43. 'applyBill',
  44. 'addTrolleyFromOrder',
  45. 'cancelApply',
  46. 'refundExpress',
  47. 'orderRefund',
  48. 'createOrderByOrder',
  49. ];
  50. public function initialize()
  51. {
  52. parent::initialize();
  53. parent::checkLogin();
  54. }
  55. /**
  56. * @title 订单确认页面(立即购买)
  57. * @desc 订单确认页面
  58. * @author qc
  59. * @url /api/Order/confirmOrderImmediately
  60. * @method GET
  61. * @header name:Authorization require:1 desc:Token
  62. * @param name:goods_id type:int require:1 default:0 desc:商品id
  63. * @param name:spec_id type:int require:1 default:0 desc:商品多规格的规格id
  64. * @param name:num type:int default:1 desc:数量
  65. * @return name:name type:string default:-- desc:商品名称
  66. * @return name:cover type:string default:-- desc:商品封面图
  67. * @return name:desc type:string default:-- desc:商品简述(副标题)
  68. * @return name:freight_type type:int default:-- desc:运费类型0固定金额,1运费模板
  69. * @return name:freight_id type:int default:-- desc:模板id(freight_type=1)
  70. * @return name:postage type:float default:-- desc:运费(freight_type=0)
  71. * @return name:total_price type:float default:-- desc:商品金额[不含运费]
  72. * @return name:freight type:float default:-- desc:运费
  73. * @return name:freight_code type:int default:1 desc:运费提示编号【1所选地址支持发货,0所选地址不支持发货】
  74. * @return name:freight_msg type:string default:-- desc:运费提示信息【freight_code=1忽略】
  75. * @return name:goods_no type:string default:-- desc:规格货号
  76. * @return name:goods_spec type:string default:-- desc:规格
  77. * @return name:sell_price type:float default:-- desc:售价
  78. * @return name:add_info type:array default:-- desc:默认收货地址(设置才有)
  79. * @return name:add_info.pro_id type:int default:-- desc:省id
  80. * @return name:add_info.city_id type:int default:-- desc:市id
  81. * @return name:add_info.county_id type:int default:-- desc:县区id
  82. * @return name:add_info.pro_name type:string default:-- desc:省名
  83. * @return name:add_info.city_name type:string default:-- desc:市名
  84. * @return name:add_info.county_name type:string default:-- desc:县区名
  85. * @return name:add_info.detail type:string default:-- desc:详细地址
  86. * @return name:add_info.phone type:string default:-- desc:联系电话
  87. * @return name:add_info.name type:string default:-- desc:联系人
  88. * @return name:freight type:float default:-- desc:运费
  89. * @return name:freight_code type:int default:1 desc:运费提示编号【1所选地址支持发货,0所选地址不支持发货】
  90. * @return name:freight_msg type:string default:-- desc:运费提示信息【freight_code=1忽略】
  91. */
  92. public function confirmOrderImmediately(){
  93. $goods_id = input('get.goods_id');
  94. $spec_id = input('get.spec_id');
  95. $num = input('get.num',1);
  96. $field = 'id,name,cover,desc,low_price,status,is_deleted,freight_type,postage,freight_id';
  97. $goods_info = StoreGoods::field($field)->where('id',$goods_id)->find()->toArray();
  98. $spec_info = StoreGoodsItem::where('id',$spec_id)->find()->toArray();
  99. $goods_info['total_price']= bcmul($spec_info['sell_price'],$num,2);
  100. $goods_info['goods_spec']= $spec_info['goods_spec'];
  101. $goods_info['goods_no']= $spec_info['goods_no'];
  102. $goods_info['sell_price']= $spec_info['sell_price'];
  103. $add_info = DeliveryAddress::where(['user_id'=>$this->user_id,'is_mr'=>1])->find();
  104. $freight = 0;
  105. if($add_info){
  106. $goods_freight = ExpressService::getGoodsExpressPrice($goods_info,$add_info->id,$num);
  107. if($goods_freight['code'] !=200){
  108. $this->is_commit = false;
  109. $this->ret_msg = $goods_freight['msg'];
  110. }
  111. if($goods_freight['code'] == 200) $freight = $goods_freight['freight'];
  112. }
  113. $this->success('ok',['goods_info'=>$goods_info,
  114. 'add_info' =>$add_info ? $add_info->toArray():null,
  115. 'freight' =>$freight,
  116. 'freight_msg' => $this->ret_msg,
  117. 'freight_code' => $this->is_commit ? 1 :0
  118. ]);
  119. }
  120. /**
  121. * @title 生成订单(立即购买)
  122. * @desc 立即购买场景
  123. * @author qc
  124. * @url /api/Order/createOrderImmediately
  125. * @method POST
  126. * @header name:Authorization require:1 desc:Token
  127. * @param name:goods_id type:int require:1 default:0 desc:商品id
  128. * @param name:spec_id type:int require:1 default:0 desc:商品多规格的规格id
  129. * @param name:num type:int default:1 desc:数量
  130. * @param name:add_id type:int default:1 desc:收货地址id
  131. * @param name:remark type:string default:1 desc:订单备注
  132. *
  133. * @param name:bill_info type:string default:-- desc:发票信息--json【不开票可以不传】
  134. * @param name:bill_info.type type:int default:-- desc:类型id
  135. * @param name:bill_info.header type:string default:-- desc:抬头名称[公司名称||个人名称]
  136. * @param name:bill_info.identify_number type:string default:-- desc:纳税人识别号
  137. * @param name:bill_info.email type:string default:-- desc:邮箱
  138. * @param name:bill_info.remark type:string default:-- desc:备注
  139. *
  140. * @return name:order_id type:int default:1 desc:订单id
  141. */
  142. public function createOrderImmediately()
  143. {
  144. $goods_id = input('post.goods_id');
  145. $spec_id = input('post.spec_id');
  146. $num = input('post.num');
  147. $add_id = input('post.add_id');
  148. $remark = input('post.remark');
  149. $post_bill = input('post.bill_info');
  150. $bill_info = json_decode(stripslashes($post_bill),true);
  151. if(!$goods_id || !$spec_id) $this->error('请选择商品');
  152. if($num <=0 ) $this->error('数量有误');
  153. if(!$add_id ) $this->error('请选择收货地址');
  154. Db::startTrans();
  155. try {
  156. $add_info = DeliveryAddress::find($add_id)->toArray();
  157. $order_insert = [
  158. 'user_id' => $this->user_id,
  159. 'order_no' => get_order_sn(),
  160. 'goods_num' => $num,
  161. 'pro_name' => $add_info['pro_name'],
  162. 'city_name' => $add_info['city_name'],
  163. 'county_name' => $add_info['county_name'],
  164. 'user_name' => $add_info['name'],
  165. 'add_detail' => $add_info['detail'],
  166. 'phone' => $add_info['phone'],
  167. 'remark' => $remark,
  168. 'address_id' => $add_id,
  169. 'int_cash' => 0.00,
  170. 'coupon_cash' => 0.00,
  171. 'blance' => 0.00
  172. ];
  173. $goods_info = StoreGoods::with(['itemList'=>function($query)use($spec_id){
  174. return $query->where('id',$spec_id)->where('is_deleted',0);
  175. }])->where('id',$goods_id)->where('is_deleted',0)->where('status',1)->find();
  176. if(!$goods_info) throw new Exception('商品已下架');
  177. $goods_info = $goods_info->toArray();
  178. if(empty($goods_info['item_list'])) throw new Exception('该规格已下架');
  179. if($goods_info['item_list'][0]['stock'] < $num) throw new Exception('库存不足');
  180. $order_insert['original_price'] = bcmul($num,$goods_info['item_list'][0]['original_price'],2);// 原价
  181. $true_cost = $goods_info['item_list'][0]['sell_price'];//实际售价
  182. $spec_info = $goods_info['item_list'][0];
  183. $price_goods = bcmul($num,$true_cost,2); // 需要支付商品价格
  184. // 获取运费信息
  185. $exp_data = ExpressService::getGoodsExpressPrice($goods_info,$add_info,$num);
  186. if($exp_data['code'] != 200 ) throw new Exception($exp_data['msg']);
  187. $price_express = $exp_data['freight']; // 商品运费
  188. //订单金额 = 商品金额 + 运费
  189. $order_money = bcadd($price_goods,$price_express ,2);
  190. if($order_money < 0) $this->exception('订单金额有误');
  191. $order_insert['price_total'] = $order_money;
  192. $order_insert['price_goods'] = $price_goods;
  193. $order_insert['price_express'] = $price_express;
  194. $order_info = GoodsOrder::create($order_insert);
  195. $order_item = [
  196. 'user_id' => $this->user_id,
  197. 'order_id' => $order_info->id,
  198. 'goods_id' => $goods_id,
  199. 'goods_no' => $spec_info['goods_no'],
  200. 'goods_spec' => $spec_info['goods_spec'],
  201. 'goods_name' => $goods_info['name'],
  202. 'spec_title' => $spec_info['spec_title'],
  203. 'spec_id' => $spec_info['id'],
  204. 'cover' => $spec_info['spec_cover'],
  205. 'original_price' => $spec_info['original_price'],
  206. 'sell_price' => $true_cost,
  207. 'pay_price' => $order_money,
  208. 'num' => $num,
  209. ];
  210. GoodsOrderItem::create($order_item);
  211. StoreGoods::where('id',$goods_id)->setDec('stock',$num);
  212. StoreGoodsItem::where('id',$spec_id)->setDec('stock',$num);
  213. // 申请开票
  214. if($order_money > 0 && !empty($bill_info)){
  215. $ret_val = UserSynth::buildBillApply($this->user_id, $order_info->id,2,$bill_info,0,1,$bill_info['remark'],0);
  216. if($ret_val['code'] != 200) $this->exception($ret_val['msg']);
  217. }
  218. Db::commit();
  219. }catch (\Exception $e){
  220. $this->is_commit = false;
  221. $this->ret_msg = $e->getMessage();
  222. Db::rollback();
  223. }
  224. $this->is_commit ? $this->success('添加成功',['order_id'=>$order_info->id]):$this->error($this->ret_msg);
  225. }
  226. /**
  227. * @title 生成订单(购物车)
  228. * @desc 购物车场景
  229. * @author qc
  230. * @url /api/Order/createOrderByTrolley
  231. * @method POST
  232. * @header name:Authorization require:1 desc:Token
  233. * @param name:ids type:int require:1 default:0 desc:购物车记录id
  234. * @param name:add_id type:int default:1 desc:收货地址id
  235. * @param name:remark type:string default:1 desc:订单备注
  236. *
  237. * @param name:bill_info type:string default:-- desc:发票信息--json【不开票可以不传】
  238. * @param name:bill_info.type type:int default:-- desc:类型id
  239. * @param name:bill_info.header type:string default:-- desc:抬头名称[公司名称||个人名称]
  240. * @param name:bill_info.identify_number type:string default:-- desc:纳税人识别号
  241. * @param name:bill_info.email type:string default:-- desc:邮箱
  242. * @param name:bill_info.remark type:string default:-- desc:备注
  243. *
  244. * @return name:order_id type:int default:1 desc:订单id
  245. */
  246. public function createOrderByTrolley()
  247. {
  248. $ids = input('post.ids');
  249. $add_id = input('post.add_id');
  250. $remark = input('post.remark');
  251. $post_bill = input('post.bill_info');
  252. $bill_info = json_decode(stripslashes($post_bill),true);
  253. if(!$ids) $this->error('请选择商品');
  254. if(!$add_id ) $this->error('请选择收货地址');
  255. $ret_data = ['order_id'=>0];
  256. Db::startTrans();
  257. try{
  258. $add_info = DeliveryAddress::where('id',$add_id)->find()->toArray();
  259. $trolley_list = ShoppingTrolley::with(['goodsSpec','goodsInfo'])->where('id','in',$ids)->select()->toArray();
  260. if(empty($trolley_list)) $this->exception('购物车记录有误');
  261. // 计算运费
  262. $price_express = 0;// 总运费
  263. $goods_list = ShoppingTrolley::where('id','in',$ids)->field('goods_id,sum(num) as total_num')->group('goods_id')->select()->toArray();
  264. foreach ($goods_list as $v){
  265. $goods_info = StoreGoods::field('name,freight_type,freight_id,postage')->where('id',$v['goods_id'])->find()->toArray();
  266. $freight_data = ExpressService::getGoodsExpressPrice($goods_info,$add_info,$v['total_num']);
  267. if($freight_data['code'] != 200){
  268. $this->exception($goods_info['name'].$freight_data['msg']);
  269. break;
  270. }
  271. $price_express += $freight_data['freight'];
  272. }
  273. // 计算运费 end
  274. $price_goods = 0; // 商品总金额
  275. $original_total = 0; // 商品总原价
  276. $total_num = 0;// 商品总数量
  277. $order_item = [];// 订单列表
  278. foreach ($trolley_list as $trolley)
  279. {
  280. //验证库存
  281. if( $trolley['goods_spec']['stock'] < $trolley['num']) $this->exception('商品库存不足');
  282. // 扣除库存
  283. StoreGoodsItem::stockChange($trolley['spec_id'],$trolley['goods_id'],$trolley['num'],-1);
  284. $price_goods += $trolley['num'] * $trolley['goods_spec']['sell_price'];
  285. $original_total += $trolley['num'] * $trolley['goods_spec']['original_price'];
  286. $total_num +=$trolley['num'];
  287. $order_item[] = [
  288. 'user_id' => $this->user_id,
  289. 'goods_id' => $trolley['goods_id'],
  290. 'goods_no' => $trolley['goods_spec']['goods_no'],
  291. 'goods_name' => $trolley['goods_info']['name'],
  292. 'goods_spec' => $trolley['goods_spec']['goods_spec'],
  293. 'spec_title' => $trolley['goods_spec']['spec_title'],
  294. 'spec_id' => $trolley['spec_id'],
  295. 'cover' => $trolley['goods_spec']['spec_cover'],
  296. 'original_price' => $trolley['goods_spec']['original_price'],
  297. 'sell_price' => $trolley['goods_spec']['sell_price'],
  298. 'num' => $trolley['num'],
  299. 'trolley_id' => $trolley['id'],
  300. ];
  301. }
  302. $order_insert = [
  303. 'user_id' => $this->user_id,
  304. 'order_no' => get_order_sn(),
  305. 'goods_num' => $total_num,
  306. 'pro_name' => $add_info['pro_name'],
  307. 'city_name' => $add_info['city_name'],
  308. 'county_name' => $add_info['county_name'],
  309. 'user_name' => $add_info['name'],
  310. 'add_detail' => $add_info['detail'],
  311. 'phone' => $add_info['phone'],
  312. 'remark' => $remark,
  313. 'address_id' => $add_id,
  314. 'int_cash' => 0.00,
  315. 'coupon_cash' => 0.00,
  316. 'blance' => 0.00
  317. ];
  318. $price_total = bcadd($price_goods ,$price_express,2);
  319. $order_insert['price_total'] = $price_total;
  320. $order_insert['price_goods'] = $price_goods ;
  321. $order_insert['original_total'] = $original_total ;
  322. $order_insert['price_express'] = $price_express ;
  323. $order_info = GoodsOrder::create($order_insert);// 生成订单
  324. array_walk($order_item,function (&$v,$k)use ($order_info){
  325. $v['order_id'] = $order_info->id;
  326. });
  327. (new GoodsOrderItem())->insertAll($order_item);// 生成订单商品详情
  328. ShoppingTrolley::where('id','in',$ids)->delete();// 删除购物车
  329. $ret_data['order_id'] = $order_info->id;
  330. // 申请开票
  331. if($price_total > 0 && !empty($bill_info)){
  332. $ret_val = UserSynth::buildBillApply($this->user_id, $order_info->id,2,$bill_info,0,1,$bill_info['remark'],0);
  333. if($ret_val['code'] != 200) $this->exception($ret_val['msg']);
  334. }
  335. Db::commit();
  336. }catch (\Exception $e){
  337. $this->ret_msg = $e->getMessage();
  338. $this->is_commit = false;
  339. Db::rollback();
  340. }
  341. $this->transReturn($ret_data);
  342. }
  343. /**
  344. * @title 订单支付
  345. * @desc 订单支付
  346. * @author qc
  347. * @url /api/Order/payOrder
  348. * @method POST
  349. * @header name:Authorization require:1 desc:Token
  350. * @param name:order_id type:int require:1 default:0 desc:订单id
  351. * @param name:pay_type type:int require:1 default:0 desc:支付方式(1.h5微信,2.h5支付宝,3移动支付(微信),4移动支付(支付宝),5.h5微信内支付,6微信pc,7pc支付宝)
  352. * @return name:config type:array default:0 desc:小程序支付配置
  353. * @return name:config.appId type:string default:-- desc:公众账号ID(小程序支付)
  354. * @return name:config.signType type:string default:-- desc:签名类型(小程序支付)
  355. * @return name:config.paySign type:string default:-- desc:签名(小程序支付)
  356. * @return name:config.nonceStr type:string default:-- desc:随机字符串(小程序支付&&APP支付)
  357. * @return name:config.timestamp type:string default:-- desc:时间戳小程序支付&&APP支付)
  358. * @return name:config.partnerid type:string default:-- desc:商户号(App支付)
  359. * @return name:config.prepayid type:string default:-- desc:唯一支付号(App支付)
  360. * @return name:config.package type:string default:-- desc:package(App支付)
  361. * @return name:config.sign type:string default:-- desc:签名(App支付)
  362. * @return name:code_url type:string default:-- desc:付款码url
  363. */
  364. public function payOrder()
  365. {
  366. $order_id = input('post.order_id');
  367. $pay_type = input('post.pay_type');
  368. $order_info = GoodsOrder::with('orderItem')->where('id',$order_id)->find()->toArray();
  369. if($order_info['status'] != 0) $this->error('订单状态错误');
  370. if($order_info['cancel_state'] != 0 || $order_info['is_deleted'] != 0) $this->error('订单异常');
  371. if($order_info['price_total'] <= 0) $this->error('订单金额错误');
  372. $pay_no = $order_info['pay_no'] ? $order_info['pay_no'] : get_order_sn();// 支付单号
  373. if(!$order_info['pay_no']) GoodsOrder::where('id',$order_id)->update(['pay_no'=>$pay_no]);
  374. $user_info = User::with('wallet')->where('id',$this->user_id)->find()->toArray();
  375. 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('微信支付冲突,请选择支付宝支付');
  376. $ret_data = ['pay_status'=>0,'config'=>[],'code_url'=>''];
  377. Db::startTrans();
  378. GoodsOrder::where('id',$order_id)->update(['pay_type'=>$pay_type]);
  379. try {
  380. switch ($pay_type){
  381. case 1://微信
  382. $notify_url = $this->request->root(true) . '/api/we_chat_pay/goodsOrderNotify';
  383. $pay_config = WeChatPay::wxPay('订单支付',$pay_no,$order_info['price_total'],$notify_url,'MWEB');
  384. if($pay_config['code'] != 200) $this->exception($pay_config['msg']);
  385. $pay_config['config']['mch_id'] = config('app.wx_pay')['mch_id'];
  386. $pay_config['config']['pay_no'] = $pay_no;
  387. $pay_config['config']['notify_url'] = $notify_url;
  388. $pay_config['config']['mweb_url'] = $pay_config['mweb_url'];
  389. $pay_config['config']['total_fee'] = $order_info['price_total'] * 100;
  390. $ret_data['config'] = $pay_config['config'];
  391. break;
  392. case 2:
  393. $notify_url = $this->request->root(true) . '/api/Alipay/goodsOrderNotify';
  394. $return_url ='https://'.$_SERVER['HTTP_HOST']."/dist/#/my";
  395. $config = Alipay::ali_pay_h5('订单支付',$pay_no,$order_info['price_total'],$notify_url,$return_url);
  396. $ret_data['config']['ali_url'] = $config;
  397. $ret_data['ali_url'] = $config;
  398. break;
  399. case 3: //移动支付(微信)
  400. $notify_url = $this->request->root(true) . '/api/we_chat_pay/goodsOrderNotify';
  401. $pay_config = WeChatPay::wxPay('订单支付',$pay_no,$order_info['price_total'],$notify_url,'APP');
  402. if($pay_config['code'] != 200) $this->exception($pay_config['msg']);
  403. $ret_data['config'] = $pay_config['config'];
  404. break;
  405. case 4://移动支付(支付宝)
  406. $notify_url = $this->request->root(true) . '/api/Alipay/goodsOrderNotify';
  407. $config = Alipay::ali_pay('订单支付',$pay_no,$order_info['price_total'],$notify_url);
  408. $ret_data['config']['ali_url'] = $config;
  409. $ret_data['ali_url'] = $config;
  410. break;
  411. case 5 :
  412. if(!$user_info['openid']) $this->exception('请绑定openid');
  413. $notify_url = $this->request->root(true) . '/api/we_chat_pay/goodsOrderNotify';
  414. $pay_config = WeChatPay::wxPay('订单支付',$pay_no,$order_info['price_total'],$notify_url,'JSAPI',$user_info['openid']);
  415. if($pay_config['code'] != 200) $this->exception($pay_config['msg']);
  416. $ret_data['config'] = $pay_config['config'];
  417. break;
  418. case 6:
  419. $notify_url = $this->request->root(true) . '/api/we_chat_pay/goodsOrderNotify';
  420. $pay_config = WeChatPay::wxPay('订单支付',$pay_no,$order_info['price_total'] ,$notify_url,'NATIVE');
  421. $ret_data['config'] = $pay_config['config'];
  422. $ret_data['code_url'] = $pay_config['pc_pay_url'];
  423. break;
  424. case 7:
  425. $notify_url = $this->request->root(true) . '/api/Alipay/goodsOrderNotify';
  426. $return_url ='https://'.$_SERVER['HTTP_HOST']."/pc/?#/product/my-order#";
  427. $config = Alipay::ali_pay_pc('订单支付',$pay_no,$order_info['price_total'],$notify_url,$return_url);
  428. $ret_data['config']['ali_url'] = $config;
  429. $ret_data['ali_url'] = $config;
  430. break;
  431. }
  432. Db::commit();
  433. }catch (\Exception $e){
  434. $this->is_commit = false;
  435. $this->ret_msg = $e->getMessage();
  436. Db::rollback();
  437. }
  438. $this->transReturn($ret_data);
  439. }
  440. /**
  441. * @title 获取订单列表
  442. * @desc 获取订单列表
  443. * @author qc
  444. * @method GET
  445. * @url /api/Order/getOrderList
  446. * @header name:Authorization require:1 desc:Token
  447. * @param name:page type:int default:1 desc:页数
  448. * @param name:page_num type:int default:20 desc:每页数
  449. * @param name:search_key type:string default:20 desc:关键字搜索[订单号]
  450. * @param name:status type:int default:-1 desc:订单状态(0待支付,1已支付(待发货),2已发货(待收货),3已收货(已完成),8已退款,9取消)
  451. * @param name:pay_state type:int default:-1 desc:支付状态(-1全部,0未支付,1已支付)
  452. * @param name:cancel_state type:int default:-1 desc:取消状态(-1全部,0未取消,1已取消)
  453. * @param name:apply_refund type:int default:-1 desc:申请退款状态(-1全部,0未申请||已取消,1已申请)
  454. * @return name:id type:int default:-- desc:订单id
  455. * @return name:id type:int default:-- desc:订单id
  456. * @return name:auto_time type:int default:-- desc:自动取消时间单位秒
  457. * @return name:expire_time type:string default:-- desc:支付到期时间
  458. * @return name:order_no type:string default:-- desc:订单号
  459. * @return name:price_total type:float default:-- desc:待支付金额(商品价格+运费)
  460. * @return name:price_goods type:float default:-- desc:商品金额
  461. * @return name:price_express type:float default:-- desc:运费金额
  462. * @return name:pay_state type:int default:-- desc:支付状态(0未支付1已支付)
  463. * @return name:pay_type type:int default:-- desc:支付方式(1.h5微信,2.h5支付宝,3移动支付(微信),4移动支付(支付宝),5.h5微信内支付)
  464. * @return name:pay_no type:string default:-- desc:支付号
  465. * @return name:pay_at type:string default:-- desc:支付时间
  466. * @return name:cancel_state type:int default:-- desc:取消状态(0未取消1已取消)
  467. * @return name:cancel_at type:string default:-- desc:取消时间
  468. * @return name:refund_state type:int default:-- desc:退款状态(0未申请1待审核,2审核拒绝,3审核通过)
  469. * @return name:express_state type:int default:-- desc:发货状态(0未发货,1已发货,2已签收)
  470. * @return name:express_company_title type:string default:-- desc:发货快递公司名称
  471. * @return name:express_send_no type:string default:-- desc:物流单号
  472. * @return name:express_send_at type:string default:-- desc:发货时间
  473. * @return name:status type:int default:-- desc:订单状态(0待支付,1已支付(待发货),2已发货(待收货),3已收货(已完成),8已退款,9取消)
  474. * @return name:create_at type:string default:-- desc:下单时间
  475. * @return name:remark type:string default:-- desc:订单备注
  476. * @return name:goods_num type:int default:-- desc:订单商品总数量
  477. * @return name:pro_name type:string default:-- desc:省名称(收货地址)
  478. * @return name:city_name type:string default:-- desc:市名称(收货地址)
  479. * @return name:county_name type:string default:-- desc:县区名称(收货地址)
  480. * @return name:add_detail type:string default:-- desc:详细地址(收货地址)
  481. * @return name:user_name type:string default:-- desc:收货人
  482. * @return name:phone type:string default:-- desc:收货人联系电话
  483. * @return name:take_time type:string default:-- desc:收货时间
  484. * @return name:order_item type:array default:-- desc:订单商品列表
  485. * @return name:order_item.name type:float default:-- desc:商品名
  486. * @return name:order_item.spec_cover type:float default:-- desc:商品图
  487. * @return name:order_item.sell_price type:float default:-- desc:购买价格
  488. * @return name:order_item.goods_spec type:float default:-- desc:规格
  489. * @return name:order_item.num type:int default:-- desc:数量
  490. *
  491. * @return name:bill_info type:array default:-- desc:发票申请信息
  492. * @return name:bill_info.header type:string default:0 desc:抬头
  493. * @return name:bill_info.type type:int default:0 desc:发票类型
  494. * @return name:bill_info.email type:string default:0 desc:邮箱
  495. * @return name:bill_info.phone type:string default:0 desc:电话
  496. * @return name:bill_info.bank type:string default:0 desc:开户行
  497. * @return name:bill_info.card_no type:string default:0 desc:银行账号
  498. * @return name:bill_info.identify_number type:string default:0 desc:纳税人识别号
  499. * @return name:bill_info.bill_img type:string default:0 desc:点子发票url
  500. * @return name:bill_info.remark type:string default:0 desc:备注
  501. *
  502. * @return name:order_refund type:array default:-- desc:申请售后信息[为空未申请]
  503. * @return name:order_refund.status type:int default:-- desc:0待审核1审核同意2审核拒绝3通过且退款4退款异常5取消申请
  504. * @return name:order_refund.audit_desc type:string default:-- desc:审核描述
  505. * @return name:order_refund.refund_type type:int default:-- desc:1退款2退货退款
  506. * @return name:order_refund.refund_money type:int default:-- desc:退款金额
  507. * @return name:order_refund.apply_case type:string default:-- desc:申请原因
  508. * @return name:order_refund.apply_remark type:string default:-- desc:描述
  509. * @return name:order_refund.express_no type:string default:-- desc:退货单号
  510. * @return name:order_refund.express_company type:string default:-- desc:快递公司
  511. * @return name:order_refund.consignee_add type:string default:-- desc:收货地址
  512. * @return name:order_refund.consignee_name type:string default:-- desc:收货人
  513. * @return name:order_refund.consignee_tel type:string default:-- desc:收货人电话
  514. */
  515. public function getOrderList()
  516. {
  517. $status = input('get.status',-1);
  518. $pay_state = input('get.pay_state',-1);
  519. $cancel_state = input('get.cancel_state',-1);
  520. $refund_state = input('get.apply_refund',-1);
  521. $search_key = input('get.search_key');
  522. $where = [];
  523. $where[] = ['user_id','=',$this->user_id];
  524. $where[] = ['is_deleted','=',0];
  525. if($status > -1) $where[] = ['status','=',$status];
  526. if($pay_state > -1) $where[] = ['pay_state','=',$pay_state];
  527. if($cancel_state > -1) $where[] = ['cancel_state','=',$cancel_state];
  528. if($refund_state == 0) $where[] = ['refund_state','=',$refund_state];
  529. if($refund_state == 1) $where[] = ['refund_state','in','1,2,3,4'];
  530. if($search_key) $where[] = ['order_no','like','%'.$search_key.'%'];
  531. $field = 'id,order_no,price_total,take_time,price_goods,price_express,create_at,pay_at,status,pay_type,goods_num,remark,pro_name,city_name,county_name,add_detail,pay_state,user_name,phone,remark,cancel_state,cancel_at,refund_state,express_state,express_company_title,express_send_no,express_send_at';
  532. $list = GoodsOrder::with(['orderItem','orderRefund'])->field($field)->where($where)->order('id desc ')
  533. ->limit($this->off_set,$this->page_num)
  534. ->select()->toArray();
  535. foreach ($list as &$info) {
  536. $auto_time = 86400 - (time() - strtotime($info['create_at'])) ;
  537. $info['auto_time'] = $auto_time > 0 && $info['status'] == 0 ? $auto_time :0;
  538. $info['expire_time'] = date('Y-m-d H:i:s',strtotime($info['create_at'])+ 86400);
  539. $bill_info = BillApply::field('id,header,type,phone,email,bank,card_no,identify_number,bill_img,remark')->where(['order_type'=>2,'order_id'=>$info['id']])->find();
  540. $info['bill_info'] = !empty($bill_info) ? $bill_info->toArray() : null;
  541. foreach ($info['order_item'] as &$v) {
  542. $v['goods_spec'] = str_replace(['::',';;'],[':',';'],$v['goods_spec']);
  543. }
  544. if(isset($info['order_refund']) )$info['order_refund']['case_title'] = OrderRefundCase::getCaseTitle($info['order_refund']['apply_case']);
  545. }
  546. $total_num = GoodsOrder::where($where)->count();
  547. $this->success('ok',['list'=>$list,'total_count'=>$total_num,'page_num'=>$this->page_num]);
  548. }
  549. /**
  550. * @title 获取订单详情
  551. * @desc 获取订单详情
  552. * @author qc
  553. * @method GET
  554. * @url /api/Order/getOrderDetail
  555. * @header name:Authorization require:1 desc:Token
  556. * @param name:order_id type:int default:-- desc:订单id
  557. * @return name:id type:int default:-- desc:订单id
  558. * @return name:order_no type:string default:-- desc:订单号
  559. * @return name:price_total type:float default:-- desc:待支付金额(商品价格+运费)
  560. * @return name:price_goods type:float default:-- desc:商品金额
  561. * @return name:price_express type:float default:-- desc:运费金额
  562. * @return name:pay_state type:int default:-- desc:支付状态(0未支付1已支付)
  563. * @return name:pay_type type:int default:-- desc:支付方式(1.h5微信,2.h5支付宝,3移动支付(微信),4移动支付(支付宝),5.h5微信内支付)
  564. * @return name:pay_no type:string default:-- desc:支付号
  565. * @return name:pay_at type:string default:-- desc:支付时间
  566. * @return name:cancel_at type:string default:-- desc:取消时间
  567. * @return name:refund_state type:int default:-- desc:退款状态(0未申请1待审核,2审核拒绝,3审核通过)
  568. * @return name:express_state type:int default:-- desc:发货状态(0未发货,1已发货,2已签收)
  569. * @return name:express_company_title type:string default:-- desc:发货快递公司名称
  570. * @return name:express_send_no type:string default:-- desc:物流单号
  571. * @return name:express_send_at type:string default:-- desc:发货时间
  572. * @return name:status type:int default:-- desc:订单状态(0待支付,1已支付(待发货),2已发货(待收货),3已收货(已完成),8已退款,9取消)
  573. * @return name:create_at type:string default:-- desc:下单时间
  574. * @return name:remark type:string default:-- desc:订单备注
  575. * @return name:auto_time type:int default:-- desc:自动取消时间单位秒
  576. * @return name:goods_num type:int default:-- desc:订单商品总数量
  577. * @return name:pro_name type:string default:-- desc:省名称(收货地址)
  578. * @return name:city_name type:string default:-- desc:市名称(收货地址)
  579. * @return name:county_name type:string default:-- desc:县区名称(收货地址)
  580. * @return name:add_detail type:string default:-- desc:详细地址(收货地址)
  581. * @return name:user_name type:string default:-- desc:收货人
  582. * @return name:take_time type:string default:-- desc:收货时间
  583. * @return name:phone type:string default:-- desc:收货人联系电话
  584. * @return name:order_item type:array default:-- desc:订单商品列表(按商品id分组)
  585. * @return name:order_item.name type:float default:-- desc:商品名
  586. * @return name:order_item.spec_cover type:float default:-- desc:商品图
  587. * @return name:order_item.sell_price type:float default:-- desc:购买价格
  588. * @return name:order_item.goods_spec type:float default:-- desc:规格
  589. * @return name:order_item.num type:int default:-- desc:数量
  590. *
  591. * @return name:bill_info type:array default:-- desc:发票申请信息
  592. * @return name:bill_info.header type:string default:0 desc:抬头
  593. * @return name:bill_info.type type:int default:0 desc:发票类型
  594. * @return name:bill_info.email type:string default:0 desc:邮箱
  595. * @return name:bill_info.phone type:string default:0 desc:电话
  596. * @return name:bill_info.bank type:string default:0 desc:开户行
  597. * @return name:bill_info.card_no type:string default:0 desc:银行账号
  598. * @return name:bill_info.identify_number type:string default:0 desc:纳税人识别号
  599. * @return name:bill_info.bill_img type:string default:0 desc:点子发票url
  600. * @return name:bill_info.remark type:string default:0 desc:备注
  601. *
  602. * @return name:order_refund type:array default:-- desc:申请售后信息[为空未申请]
  603. * @return name:order_refund.status type:int default:-- desc:0待审核1审核同意2审核拒绝3通过且退款4退款异常5取消申请
  604. * @return name:order_refund.audit_desc type:string default:-- desc:审核描述
  605. * @return name:order_refund.refund_type type:int default:-- desc:1退款2退货退款
  606. * @return name:order_refund.refund_money type:int default:-- desc:退款金额
  607. * @return name:order_refund.apply_case type:string default:-- desc:申请原因
  608. * @return name:order_refund.refund_time type:string default:-- desc:退款时间
  609. * @return name:order_refund.apply_remark type:string default:-- desc:申请描述
  610. * @return name:order_refund.refund_no type:string default:-- desc:退款编号
  611. * @return name:order_refund.express_no type:string default:-- desc:退货单号
  612. * @return name:order_refund.express_company type:string default:-- desc:快递公司
  613. * @return name:order_refund.consignee_add type:string default:-- desc:收货地址
  614. * @return name:order_refund.consignee_name type:string default:-- desc:收货人
  615. * @return name:order_refund.consignee_tel type:string default:-- desc:收货人电话
  616. * @return name:order_refund.express_time type:string default:-- desc:退款后发货时间
  617. *
  618. */
  619. public function getOrderDetail()
  620. {
  621. $order_id = input('get.order_id');
  622. $field = 'id,order_no,price_total,price_goods,status,price_express,take_time ,create_at,pay_at,pay_type,goods_num,remark,pro_name,city_name,county_name,add_detail,pay_state,user_name,phone,remark,cancel_state,cancel_at,refund_state,express_state,express_company_title,express_send_no,express_send_at';
  623. $detail = GoodsOrder::with('orderRefund')->where('id',$order_id)->field($field)->find()->toArray();
  624. // if(isset($detail['order_refund']['express_info']) && $detail['order_refund']['express_info'])$info['order_refund']['express_info'] = json_decode($detail['order_refund']['express_info'],true);
  625. if(isset($detail['order_refund']) )$detail['order_refund']['case_title'] = OrderRefundCase::getCaseTitle($detail['order_refund']['apply_case']);
  626. $auto_time = 86400 - (time() - strtotime($detail['create_at'])) ;
  627. $detail['auto_time'] = $auto_time > 0 && $detail['status'] == 0 ? $auto_time :0;
  628. $detail['order_item'] = (new GoodsOrderItem())->getOrderItem($order_id);
  629. foreach ($detail['order_item'] as &$v) {
  630. $v['goods_spec'] = str_replace(['::',';;'],[':',';'],$v['goods_spec']);
  631. $good = StoreGoods::where('id',$v['goods_id'])->field('user_id')->find();
  632. $info_auth = User::where('id',$good['user_id'])->find();
  633. if($info_auth){
  634. $v['member_name'] = $info_auth['name'];
  635. $v['member_headimg'] = $info_auth['headimg'];
  636. }else{
  637. $v['member_name'] = '';
  638. $v['member_headimg'] = '';
  639. }
  640. }
  641. $bill_info = BillApply::field('id,header,type,phone,email,bank,card_no,identify_number,bill_img,remark')->where(['order_type'=>2,'order_id'=>$detail['id']])->find();
  642. $detail['bill_info'] = !empty($bill_info) ? $bill_info->toArray() : null;
  643. $this->success('ok',['detail'=>$detail]);
  644. }
  645. /**
  646. * @title 计算商品运费(一个商品)
  647. * @desc 计算商品运费(一个商品)
  648. * @author qc
  649. * @url /api/Order/getGoodsFreight
  650. * @method GET
  651. * @header name:Authorization require:1 desc:Token
  652. * @param name:goods_id type:int require:1 default:0 desc:商品id
  653. * @param name:num type:int require:1 default:0 desc:商品数量
  654. * @param name:add_id type:int require:1 default:0 desc:收货地址id
  655. * @return name:freight type:float require:0 default:0 desc运费金额
  656. */
  657. public function getGoodsFreight()
  658. {
  659. $goods_id = input('get.goods_id');
  660. $num = input('get.num');
  661. $add_id = input('get.add_id');
  662. $goods_info = StoreGoods::where('id',$goods_id)->find()->toArray();
  663. $add_info = DeliveryAddress::where('id',$add_id)->find()->toArray();
  664. $freight_data = ExpressService::getGoodsExpressPrice($goods_info,$add_info,$num);
  665. if($freight_data['code'] != 200 ) $this->error($freight_data['msg']);
  666. $this->success('ok',['freight'=>$freight_data['freight']]);
  667. }
  668. /**
  669. * @title 计算购物车商品运费
  670. * @desc 计算购物车商品运费
  671. * @author qc
  672. * @url /api/Order/getTrolleyFreight
  673. * @method GET
  674. * @header name:Authorization require:1 desc:Token
  675. * @param name:ids type:int require:1 default:0 desc:购物车商品id串(逗号隔开)
  676. * @param name:add_id type:int require:1 default:0 desc:收货地址id
  677. * @return name:freight type:float require:0 default:0 desc运费金额
  678. */
  679. public function getTrolleyFreight()
  680. {
  681. $trolley_ids = input('get.ids');
  682. $add_id = input('get.add_id');
  683. $goods_list = ShoppingTrolley::where('id','in',$trolley_ids)
  684. ->field('goods_id,sum(num) as total_num')
  685. ->group('goods_id')
  686. ->select()->toArray();
  687. $total_price = 0;
  688. $add_info = DeliveryAddress::where('id',$add_id)->find()->toArray();
  689. foreach ($goods_list as $v){
  690. $goods_info = StoreGoods::field('name,freight_type,freight_id,postage')->where('id',$v['goods_id'])->find()->toArray();
  691. $freight_data = ExpressService::getGoodsExpressPrice($goods_info,$add_info,$v['total_num']);
  692. if($freight_data['code'] != 200){
  693. $this->error($goods_info['name'].$freight_data['msg']);
  694. break;
  695. }
  696. $total_price += $freight_data['freight'];
  697. }
  698. $this->success('ok',['freight'=>$total_price]);
  699. }
  700. /**
  701. * @title 取消订单
  702. * @desc 取消订单
  703. * @author qc
  704. * @url /api/Order/cancelOrder
  705. * @method POST
  706. * @header name:Authorization require:1 desc:Token
  707. * @param name:order_id type:int require:1 default:0 desc:订单id
  708. */
  709. public function cancelOrder()
  710. {
  711. $order_id = input('post.order_id');
  712. Db::startTrans();
  713. try {
  714. $detail = GoodsOrder::with('orderItem')->where('id',$order_id)->find()->toArray();
  715. if($detail['status'] != 0) $this->exception('订单状态有误');
  716. // 取消订单状态
  717. GoodsOrder::update(['status'=>9,'cancel_state'=>1],['id'=>$order_id]);
  718. // 订单处理
  719. foreach ($detail['order_item'] as $item_info) {
  720. // 更改订单详情状态
  721. GoodsOrderItem::update(['status'=>9],['id'=>$item_info['id']]);
  722. StoreGoodsItem::stockChange($item_info['spec_id'],$item_info['goods_id'],$item_info['num']);
  723. }
  724. Db::commit();
  725. }catch (\Exception $e){
  726. $this->ret_msg = $e->getMessage();
  727. $this->is_commit = false;
  728. Db::rollback();
  729. }
  730. $this->is_commit ? $this->success('取消成功') : $this->error($this->ret_msg);
  731. }
  732. /**
  733. * @title 删除订单
  734. * @desc 删除订单
  735. * @author qc
  736. * @url /api/Order/deleteOrder
  737. * @method POST
  738. * @header name:Authorization require:1 desc:Token
  739. * @param name:order_id type:int require:1 default:0 desc:订单id
  740. */
  741. public function deleteOrder()
  742. {
  743. $order_id = input('post.order_id');
  744. $detail = GoodsOrder::with('orderItem')->where('id',$order_id)->find()->toArray();
  745. if($detail['status'] == 0) $this->error('请先取消订单');
  746. GoodsOrder::update(['is_deleted'=>1],['id'=>$order_id]);
  747. $this->success('删除成功');
  748. }
  749. /**
  750. * @title 更换订单收货地址
  751. * @desc 更换订单收货地址(仅待支付订单可以修改地址)
  752. * @author qc
  753. * @url /api/Order/changeOrderDelivery
  754. * @method POST
  755. * @header name:Authorization require:1 desc:Token
  756. * @param name:order_id type:int require:1 default:0 desc:订单id
  757. * @param name:add_id type:int require:1 default:0 desc:收货地址id
  758. */
  759. public function changeOrderDelivery()
  760. {
  761. $order_id = input('post.order_id');
  762. $add_id = input('post.add_id');
  763. $detail = GoodsOrder::where('id',$order_id)->find()->toArray();
  764. if($detail['status'] != 0) $this->error('操作错误');
  765. $add_info = DeliveryAddress::where('id',$add_id)->find()->toArray();
  766. $order_update =[
  767. 'pro_name' => $add_info['pro_name'],
  768. 'city_name' => $add_info['city_name'],
  769. 'county_name' => $add_info['county_name'],
  770. 'add_detail' => $add_info['detail'],
  771. 'user_name' => $add_info['name'],
  772. 'phone' => $add_info['phone'],
  773. ];
  774. GoodsOrder::update($order_update,['id'=>$order_id]);
  775. $this->success('修改成功');
  776. }
  777. /**
  778. * @title 确认收货
  779. * @desc 确认收货
  780. * @author qc
  781. * @url /api/Order/confirmReceipt
  782. * @method POST
  783. * @header name:Authorization require:1 desc:Token
  784. * @param name:order_id type:int require:1 default:0 desc:订单id
  785. */
  786. public function confirmReceipt()
  787. {
  788. $order_id = input('post.order_id');
  789. $detail = GoodsOrder::with('orderItem')->where('id',$order_id)->find()->toArray();
  790. if($detail['status'] == 0) $this->error('订单未支付');
  791. if($detail['status'] == 1) $this->error('订单未发货');
  792. if($detail['status'] == 3) $this->error('订单已收货');
  793. GoodsOrder::update(['status'=>3,'express_state'=>2],['id'=>$order_id]);
  794. GoodsOrderItem::update(['status'=>3,'express_state'=>2],['order_id'=>$order_id]);
  795. UserMessage::create(['user_id'=>$this->user_id,'type_id'=>3,'relation_id'=>$order_id,'content'=>'订单收货成功']);
  796. $this->success('已确认收货');
  797. }
  798. /**
  799. * @title 获取物流详情
  800. * @desc 获取物流详情
  801. * @author qc
  802. * @url /api/Order/deliveryDetails
  803. * @method GET
  804. * @header name:Authorization require:1 desc:Token
  805. * @param name:order_id type:string require:1 default:-- desc:订单id
  806. * @return name:number type:string default:-- desc:单号
  807. * @return name:type type:string default:-- desc:快递类型
  808. * @return name:list type:array default:-- desc:数据列表
  809. * @return name:list.time type:string default:-- desc:时间
  810. * @return name:list.status type:string default:-- desc:内容
  811. * @return name:deliverystatus type:int default:-- desc:0:快递收件(揽件)1.在途中2.正在派件3.已签收4.派送失败5.疑难件6.退件签收
  812. * @return name:issign type:int default:-- desc:是否签收(1.是否签收)
  813. * @return name:expName type:string default:-- desc:快递公司名称
  814. * @return name:expSite type:string default:-- desc:快递公司官网
  815. * @return name:expPhone type:string default:-- desc:快递公司电话
  816. * @return name:courier type:string default:-- desc:快递员 或 快递站(没有则为空)
  817. * @return name:courierPhone type:string default:-- desc:快递员电话 (没有则为空)
  818. * @return name:updateTime type:string default:-- desc:快递轨迹信息最新时间
  819. * @return name:takeTime type:string default:-- desc:发货到收货消耗时长 (截止最新轨迹)
  820. * @return name:logo type:string default:-- desc:快递公司LOGO
  821. */
  822. public function deliveryDetails(){
  823. $send_no = GoodsOrder::where('id',input('get.order_id'))->value('express_send_no');
  824. if(!$send_no) $this->error('订单没有发货');
  825. $data = get_delivery($send_no);
  826. if($data['issign'] == 1){
  827. $express_send_date = end($data['list']);
  828. $express_send_date = $express_send_date['time'];
  829. if($express_send_date < date('Y-m-d H:i:s',strtotime('-2 days'))){
  830. try {
  831. $detail = GoodsOrder::where('id',input('get.order_id'))->find()->toArray();
  832. $order_id = $detail['id'];
  833. // $detail = GoodsOrder::where('id',$order_id)->find()->toArray();
  834. if($detail['status'] == 0) $this->error('订单未支付');
  835. if($detail['status'] == 1) $this->error('订单未发货');
  836. if($detail['status'] == 3) $this->error('订单已收货');
  837. GoodsOrder::update(['status'=>3,'express_state'=>2],['id'=>$order_id]);
  838. GoodsOrderItem::update(['status'=>3,'express_state'=>2],['order_id'=>$order_id]);
  839. UserMessage::create(['user_id'=>$detail['user_id'],'type_id'=>3,'relation_id'=>$order_id,'content'=>'订单收货成功']);
  840. Db::commit();
  841. }catch (\Exception $e) {
  842. Db::rollback();
  843. }
  844. }
  845. }
  846. $this->success('ok',$data);
  847. }
  848. /**
  849. * @title 发货提醒
  850. * @desc 发货提醒
  851. * @author qc
  852. * @url /api/Order/orderUrge
  853. * @method POST
  854. * @header name:Authorization require:1 desc:Token
  855. * @param name:order_id type:string require:1 default:-- desc:订单id
  856. */
  857. public function orderUrge()
  858. {
  859. $order_id = input('post.order_id');
  860. $order_info = GoodsOrder::where('id',$order_id)->find();
  861. if(!$order_info ) $this->error('订单错误');
  862. if($order_info->pay_state != 1 ) $this->error('订单未支付');
  863. if($order_info->express_send_no != '' ) $this->error('订单已发货');
  864. $urge_ret = ExpressService::orderUrge($order_id,$this->user_id);
  865. $urge_ret['code'] == 200 ? $this->success($urge_ret['msg']) : $this->error($urge_ret['msg']);
  866. }
  867. /**
  868. * @title 获取订单催发记录
  869. * @desc 获取订单催发记录
  870. * @author qc
  871. * @url /api/Order/getUrgeList
  872. * @method GET
  873. * @header name:Authorization require:1 desc:Token
  874. * @param name:order_id type:string require:1 default:-- desc:订单id
  875. */
  876. public function getUrgeList()
  877. {
  878. $order_id = input('get.order_id');
  879. $list = OrderLogisticsUrge::where(['order_id'=>$order_id,'table_name'=>'dd_store_order'])->order('id desc')->select()->toArray();
  880. $this->success('ok',['list'=>$list]);
  881. }
  882. /**
  883. *
  884. * @title 申请开票
  885. * @desc 申请开票
  886. * @author qc
  887. * @method POST
  888. * @url /api/Order/applyBill
  889. * @header name:Authorization require:1 desc:Token
  890. * @param name:order_id type:string default:1 desc:订单id
  891. * @param name:type type:int default:-- desc:类型id
  892. * @param name:header type:string default:-- desc:抬头名称[公司名称||个人名称]
  893. * @param name:identify_number type:string default:-- desc:纳税人识别号
  894. * @param name:email type:string default:-- desc:邮箱
  895. * @param name:remark type:string default:-- desc:备注
  896. */
  897. public function applyBill()
  898. {
  899. $order_id = input('post.order_id');
  900. $post = input('post.');
  901. if(!isset($post['remark']) || !$post['remark']){
  902. $post['remark'] = '';
  903. }
  904. $order_info = GoodsOrder::where('id',$order_id)->find()->toArray();
  905. if($order_info['pay_state']==0)$this->error('订单未支付');
  906. if(BillApply::checkBillApply($order_id,2)) $this->error('已申请开票');
  907. $ret_val = UserSynth::buildBillApply($this->user_id, $order_id, 2,$post,0,1,$post['remark']);
  908. if($ret_val['code'] != 200) $this->error($ret_val['msg']);
  909. $this->success('申请成功');
  910. }
  911. /**
  912. *
  913. * @title 订单商品添加购物车
  914. * @desc 订单商品添加购物车
  915. * @author qc
  916. * @method POST
  917. * @url /api/Order/addTrolleyFromOrder
  918. * @header name:Authorization require:1 desc:Token
  919. * @param name:order_id type:string default:1 desc:订单id
  920. */
  921. public function addTrolleyFromOrder(){
  922. $order_id = input('post.order_id');
  923. Db::startTrans();
  924. try {
  925. $detail = GoodsOrder::with('orderItem')->where('id',$order_id)->find()->toArray();
  926. foreach ($detail['order_item'] as $item_info) {
  927. $goods_info = StoreGoods::getGoodsSpec($item_info['goods_id'],$item_info['spec_id']);
  928. if(!$goods_info) $this->exception('商品已下架');
  929. if(empty($goods_info['item_list'])) $this->exception('商品规格已下架');
  930. if($goods_info['item_list'][0]['stock'] < $item_info['num'])$this->exception('库存不足');
  931. //某商品某规格是否已经添加购物车
  932. $trolley_id = ShoppingTrolley::checkTrolley($this->user_id,$item_info['goods_id'],$item_info['spec_id']);
  933. // 添加到购物车
  934. if($trolley_id) {
  935. ShoppingTrolley::where('id',$trolley_id)->setInc('num',$item_info['num']);
  936. }else{
  937. $trolley_info = [
  938. 'user_id' => $this->user_id,
  939. 'goods_id' => $item_info['goods_id'],
  940. 'spec_id' => $item_info['spec_id'],
  941. 'goods_no' => $goods_info['item_list'][0]['goods_no'],
  942. 'num' => $item_info['num'],
  943. ];
  944. ShoppingTrolley::create($trolley_info);
  945. }
  946. }
  947. Db::commit();
  948. }catch (\Exception $e){
  949. $this->ret_msg = $e->getMessage();
  950. $this->is_commit = false;
  951. Db::rollback();
  952. }
  953. $this->is_commit ? $this->success('添加成功') : $this->error($this->ret_msg);
  954. }
  955. /**
  956. * @title 获取退款理由
  957. * @desc 获取退款理由
  958. * @author qc
  959. * @url /api/Order/getRefundCase
  960. * @method GET
  961. * @header name:Authorization require:1 desc:Token
  962. * @param name:id type:string default:0 desc:id
  963. * @param name:title type:string default:0 desc:标题
  964. */
  965. public function getRefundCase()
  966. {
  967. $list= OrderRefundCase::where('is_deleted',0)->order('sort desc ,id desc')->select();
  968. $this->success('ok',['list'=>$list]);
  969. }
  970. /**
  971. * @title 取消退款申请
  972. * @desc 取消退款申请
  973. * @author qc
  974. * @url /api/Order/cancelApply
  975. * @method POST
  976. * @header name:Authorization require:1 desc:Token
  977. * @param name:order_id type:int require:1 default:0 desc:订单id
  978. */
  979. public function cancelApply()
  980. {
  981. $order_id = input('post.order_id');
  982. $field = 'id,order_no,price_total,price_goods,price_express,create_at,pay_at,pay_type,goods_num,remark,pro_name,city_name,county_name,add_detail,pay_state,user_name,phone,remark,cancel_state,cancel_at,refund_state,express_state,express_company_title,express_send_no,express_send_at';
  983. $order_info = GoodsOrder::with('orderRefund')->where('id',$order_id)->field($field)->find()->toArray();
  984. //express_on express_company
  985. if(!$order_info['order_refund']) $this->error('该订单未申请退款');
  986. // if($order_info['order_refund']['status'] != 0 ) $this->error('订单已审核完成');
  987. if($order_info['order_refund']['status'] == 3 ){
  988. $this->error('订单已退款');
  989. }
  990. if($order_info['order_refund']['express_no'] != null ){
  991. $this->error('订单已审核完成');
  992. }
  993. Db::startTrans();
  994. try {
  995. StoreOrderRefund::where('id',$order_info['order_refund']['id'])->update(['status'=>5,'is_deleted'=>1]);
  996. GoodsOrder::where('id',$order_id)->update(['refund_state'=>0]);
  997. Db::commit();
  998. }catch (\Exception $e) {
  999. Db::rollback();
  1000. }
  1001. $this->success('取消成功!');
  1002. }
  1003. /**
  1004. * @title 完善售后物流
  1005. * @desc 完善退款物流
  1006. * @author qc
  1007. * @url /api/Order/refundExpress
  1008. * @method POST
  1009. * @header name:Authorization require:1 desc:Token
  1010. * @param name:id type:int require:1 default:0 desc:退款记录id
  1011. * @param name:express_company type:string default:0 desc:0 desc:物流公司名称
  1012. * @param name:express_no type:string default:0 desc:快递号
  1013. */
  1014. public function refundExpress()
  1015. {
  1016. $id = input('post.id');
  1017. $express_company = input('post.express_company');
  1018. $express_no = input('post.express_no');
  1019. $info = StoreOrderRefund::where('id',$id)->find()->toArray();
  1020. if(!$info['consignee_add']) $this->error('请等待后台审核');
  1021. $exp_info = [
  1022. 'express_company'=>$express_company,
  1023. 'express_no'=>$express_no,
  1024. 'express_time'=>date("Y-m-d H:i:s"),
  1025. ];
  1026. StoreOrderRefund::where('id',$id)->update($exp_info);
  1027. $this->success('物流信息完善成功');
  1028. }
  1029. /**
  1030. * @title 订单申请退款(重新退款||退款编辑)
  1031. * @desc 订单申请退款
  1032. * @author qc
  1033. * @url /api/Order/orderRefund
  1034. * @method POST
  1035. * @header name:Authorization require:1 desc:Token
  1036. * @param name:order_id type:int require:1 default:0 desc:订单id
  1037. * @param name:apply_case type:string default:0 desc:退款原因id(多个逗号隔开)
  1038. * @param name:refund_type type:int default:0 desc:售后类型【1退款2退款退货】
  1039. * @param name:apply_remark type:string default:0 desc:描述
  1040. * @param name:images type:string default:0 desc:图片(多张|隔开)
  1041. */
  1042. public function orderRefund()
  1043. {
  1044. $order_id = input('post.order_id');
  1045. $images = input('post.images');
  1046. $apply_case = input('post.apply_case');
  1047. $refund_type = input('post.refund_type');
  1048. $apply_remark = input('post.apply_remark');
  1049. $order_info = GoodsOrder::with('orderRefund')->where('id',$order_id)->find()->toArray();
  1050. if($refund_type == 1 && $order_info['express_state'] != 0) $this->error('订单已发货');
  1051. if($refund_type == 2 && $order_info['express_state'] != 2) $this->error('订单未收货');
  1052. if($order_info['status'] == 0) $this->error('订单未支付');
  1053. if($order_info['refund_state'] == 1) $this->error('订单已申请,等待审核');
  1054. if($order_info['refund_state'] == 2) $this->error('已通过审核');
  1055. $refund_info = [
  1056. 'user_id' => $this->user_id ,
  1057. 'order_id' => $order_id ,
  1058. 'num' => $order_info['goods_num'],
  1059. 'apply_case' => $apply_case,
  1060. 'images' => $images,
  1061. 'is_deleted'=> 0,
  1062. 'order_type'=> 2,
  1063. 'status'=>0,
  1064. 'refund_money'=> $order_info['price_total'],
  1065. 'sell_price'=> $order_info['price_goods'],
  1066. 'apply_remark'=> $apply_remark,
  1067. 'refund_type'=> $order_info['express_state'] == 0 ? 1:2,
  1068. 'create_at'=> date('Y-m-d H:i:s'),
  1069. 'refund_no'=> 'R'.$order_info['order_no'],
  1070. ];
  1071. Data::save('StoreOrderRefund',$refund_info,'order_id',['order_id'=>$order_id]);
  1072. GoodsOrder::where(['id'=>$order_id])->update(['refund_state'=>1]);
  1073. $this->success('申请成功等待审核');
  1074. }
  1075. /**
  1076. * @title 获取发票详情
  1077. * @desc 获取发票详情
  1078. * @author qc
  1079. * @url /api/Order/getBillInfo
  1080. * @method GET
  1081. * @param name:id type:int require default:-- desc:订单id
  1082. * @return name:id type:array default:-- desc:票详情id
  1083. * @return name:header type:string default:0 desc:抬头
  1084. * @return name:type_title type_title:int default:0 desc:发票类型
  1085. * @return name:email type:string default:0 desc:邮箱
  1086. * @return name:create_at type:string default:0 desc:申请时间
  1087. * @return name:phone type:string default:0 desc:电话
  1088. * @return name:status type:int default:0 desc:状态(0申请中1已开票2已完成)
  1089. * @return name:identify_number type:string default:0 desc:纳税人识别号
  1090. * @return name:send_type type:string default:1 desc:1点子发票2纸质发票
  1091. * @return name:remark type:string default:0 desc:备注
  1092. * @return name:bill_img type:string default:0 desc:点子发票【图片】
  1093. * @return name:bill_time type:string default:0 desc:开票时间
  1094. *
  1095. */
  1096. public function getBillInfo()
  1097. {
  1098. $info = BillApply::where(['order_type'=>2,'order_id'=>input('get.id')])
  1099. ->alias('b')->field('b.id,b.type,b.header,b.status,b.email,b.phone,b.bill_img,b.bill_time,b.remark,identify_number,b.create_at,t.title type_title,a.price_total money')
  1100. ->leftJoin('BillType t','t.id = b.type')
  1101. ->leftJoin('StoreOrder a','a.id = b.order_id')
  1102. ->find();
  1103. if(empty($info)) $this->error('该订单未申请发票');
  1104. $info = $info->toArray();
  1105. $this->success('ok',['detail'=>$info]);
  1106. }
  1107. /**
  1108. * @title 订单再次购买--确认订单页面
  1109. * @desc 订单再次购买
  1110. * @author qc
  1111. * @url /api/Order/getOrderItem
  1112. * @method GET
  1113. * @param name:order_id type:int require default:-- desc:订单id
  1114. * @return name:id type:int require default:-- desc:订单id
  1115. * @return name:pro_name type:string default:-- desc:省名称(收货地址)
  1116. * @return name:city_name type:string default:-- desc:市名称(收货地址)
  1117. * @return name:county_name type:string default:-- desc:县区名称(收货地址)
  1118. * @return name:add_detail type:string default:-- desc:详细地址(收货地址)
  1119. * @return name:user_name type:string default:-- desc:收货人
  1120. * @return name:phone type:string default:-- desc:收货人联系电话
  1121. * @return name:remark type:string require default:-- desc:备注
  1122. * @return name:address_id type:string require default:-- desc:收货地址id
  1123. * @return name:add_info type:array require default:-- desc:收货地址详情
  1124. * @return name:order_item type:array default:-- desc:订单商品列表(按商品id分组)
  1125. * @return name:order_item.name type:float default:-- desc:商品名
  1126. * @return name:order_item.spec_cover type:float default:-- desc:商品图
  1127. * @return name:order_item.sell_price type:float default:-- desc:价格
  1128. * @return name:order_item.goods_spec type:float default:-- desc:规格
  1129. * @return name:order_item.num type:int default:-- desc:数量
  1130. * @return name:order_item.stock type:int default:-- desc:剩余库存
  1131. * @return name:order_item.is_normal type:int default:-- desc:商品状态(0无法正常售卖1正常)
  1132. * @return name:order_item.msg type:int default:-- desc:商品状态描述
  1133. * @return name:bill_info type:array default:-- desc:发票申请信息
  1134. * @return name:bill_info.header type:string default:0 desc:抬头
  1135. * @return name:bill_info.type type:int default:0 desc:发票类型
  1136. * @return name:bill_info.email type:string default:0 desc:邮箱
  1137. * @return name:bill_info.phone type:string default:0 desc:电话
  1138. * @return name:bill_info.bank type:string default:0 desc:开户行
  1139. * @return name:bill_info.card_no type:string default:0 desc:银行账号
  1140. * @return name:bill_info.identify_number type:string default:0 desc:纳税人识别号
  1141. * @return name:bill_info.bill_img type:string default:0 desc:点子发票url
  1142. * @return name:bill_info.remark type:string default:0 desc:备注
  1143. */
  1144. public function getOrderItem()
  1145. {
  1146. $order_id = input('get.order_id');
  1147. $field = 'id,remark,address_id,pro_name,city_name,county_name,add_detail,user_name,phone';
  1148. $detail = GoodsOrder::where('id',$order_id)->field($field)->find()->toArray();
  1149. $detail['order_item'] = GoodsOrderItem::getGoodsInfo($order_id);
  1150. foreach ($detail['order_item'] as &$v) {
  1151. $v['goods_spec'] = str_replace(['::',';;'],[':',';'],$v['goods_spec']);
  1152. }
  1153. $bill_info = BillApply::field('id,header,type,phone,email,bank,card_no,identify_number,bill_img,remark')->where(['order_type'=>2,'order_id'=>$detail['id']])->find();
  1154. $detail['bill_info'] = !empty($bill_info) ? $bill_info->toArray() : null;
  1155. $add_info = DeliveryAddress::where(['user_id'=>$this->user_id,'id'=>$detail['address_id'],'is_deleted'=>0])->find();
  1156. $detail['add_info'] = $add_info ? $add_info->toArray() : null;
  1157. $this->success('ok',['detail'=>$detail]);
  1158. }
  1159. /**
  1160. * @title 获取订单运费
  1161. * @desc 获取订单运费
  1162. * @author qc
  1163. * @url /api/Order/getOrderExpress
  1164. * @method GET
  1165. * @param name:id type:int require default:-- desc:订单id
  1166. * @param name:add_id type:int require default:-- desc:收货地址id
  1167. */
  1168. public function getOrderExpress()
  1169. {
  1170. $order_id = input('get.order_id');
  1171. $add_id = input('get.add_id');
  1172. // 计算运费
  1173. $add_info = DeliveryAddress::where('id',$add_id)->find()->toArray();
  1174. $goods_list = GoodsOrderItem::where('order_id',$order_id)->field('goods_id,sum(num) as total_num')->group('goods_id')->select()->toArray();
  1175. $total_price = 0;
  1176. foreach ($goods_list as $v){
  1177. $goods_info = StoreGoods::field('name,freight_type,freight_id,postage')->where('id',$v['goods_id'])->find()->toArray();
  1178. $freight_data = ExpressService::getGoodsExpressPrice($goods_info,$add_info,$v['total_num']);
  1179. if($freight_data['code'] != 200){
  1180. $this->error($goods_info['name'].$freight_data['msg']);
  1181. break;
  1182. }
  1183. $total_price += $freight_data['freight'];
  1184. }
  1185. $this->success('ok',['freight'=>$total_price]);
  1186. }
  1187. /**
  1188. * @title 订单再次购买
  1189. * @desc 订单再次购买
  1190. * @author qc
  1191. * @url /api/Order/createOrderByOrder
  1192. * @method POST
  1193. * @param name:order_id type:int require default:-- desc:订单id
  1194. * @param name:add_id type:int require default:-- desc:收货地址id
  1195. * @param name:remark type:string require default:-- desc:备注
  1196. *
  1197. * @param name:bill_info type:string default:-- desc:发票信息--json【不开票可以不传】
  1198. * @param name:bill_info.type type:int default:-- desc:类型id
  1199. * @param name:bill_info.header type:string default:-- desc:抬头名称[公司名称||个人名称]
  1200. * @param name:bill_info.identify_number type:string default:-- desc:纳税人识别号
  1201. * @param name:bill_info.email type:string default:-- desc:邮箱
  1202. * @param name:bill_info.remark type:string default:-- desc:备注
  1203. */
  1204. public function createOrderByOrder()
  1205. {
  1206. $order_id = input('post.order_id');
  1207. $add_id = input('post.add_id');
  1208. $remark = input('post.remark');
  1209. $post_bill = input('post.bill_info');
  1210. $bill_info = json_decode(stripslashes($post_bill),true);
  1211. $order_info = GoodsOrder::where('id',$order_id)->where('user_id',$this->user_id)->find()->toArray();
  1212. $item_list = GoodsOrderItem::where('order_id',$order_id)->select()->toArray();
  1213. if(!$add_id ) $this->error('请选择收货地址');
  1214. Db::startTrans();
  1215. try {
  1216. $add_info = DeliveryAddress::where('id',$add_id)->find()->toArray();
  1217. $goods_list = GoodsOrderItem::where('order_id',$order_id)->field('goods_id,sum(num) as total_num')->group('goods_id')->select()->toArray();
  1218. $price_express = 0;
  1219. foreach ($goods_list as $v){
  1220. $goods_info = StoreGoods::field('name,freight_type,freight_id,postage')->where('id',$v['goods_id'])->find()->toArray();
  1221. $freight_data = ExpressService::getGoodsExpressPrice($goods_info,$add_info,$v['total_num']);
  1222. if($freight_data['code'] != 200){
  1223. $this->exception($goods_info['name'].$freight_data['msg']);
  1224. break;
  1225. }
  1226. $price_express += $freight_data['freight'];
  1227. }
  1228. $order_insert = [
  1229. 'user_id' => $order_info['user_id'],
  1230. 'order_no' => get_order_sn(),
  1231. 'goods_num' => $order_info['goods_num'],
  1232. 'pro_name' => $add_info['pro_name'],
  1233. 'city_name' => $add_info['city_name'],
  1234. 'county_name' => $add_info['county_name'],
  1235. 'user_name' => $add_info['name'],
  1236. 'add_detail' => $add_info['detail'],
  1237. 'phone' => $add_info['phone'],
  1238. 'remark' => $remark,
  1239. 'address_id' => $add_id,
  1240. ];
  1241. $price_goods = 0; // 商品总金额
  1242. $original_total = 0; // 商品总原价
  1243. $total_num = 0;// 商品总数量
  1244. $order_item = [];// 订单列表
  1245. foreach ($item_list as $v) {
  1246. $goods_info = StoreGoods::with(['itemList'=>function($query)use($v){
  1247. return $query->where('id',$v['spec_id'])->where('is_deleted',0);
  1248. }])->where('id',$v['goods_id'])->where('is_deleted',0)->where('status',1)->find();
  1249. if(!$goods_info) throw new Exception('商品已下架');
  1250. $goods_info = $goods_info->toArray();
  1251. if(empty($goods_info['item_list'])) throw new Exception('该规格已下架');
  1252. //验证库存
  1253. if($goods_info['item_list'][0]['stock'] < $v['num']) throw new Exception('库存不足');
  1254. // 扣除库存
  1255. StoreGoodsItem::stockChange($v['spec_id'],$v['goods_id'],$v['num'],-1);
  1256. $price_goods += $v['num'] * $goods_info['item_list'][0]['sell_price'];
  1257. $original_total += $v['num'] * $goods_info['item_list'][0]['original_price'];
  1258. $total_num +=$v['num'];
  1259. $order_item[] = [
  1260. 'user_id' => $this->user_id,
  1261. 'goods_id' => $v['goods_id'],
  1262. 'goods_no' => $goods_info['item_list'][0]['goods_no'],
  1263. 'goods_name' => $goods_info['name'],
  1264. 'goods_spec' => $goods_info['item_list'][0]['goods_spec'],
  1265. 'spec_title' => $goods_info['item_list'][0]['spec_title'],
  1266. 'spec_id' => $goods_info['item_list'][0]['id'],
  1267. 'cover' => $goods_info['item_list'][0]['spec_cover'],
  1268. 'original_price' => $goods_info['item_list'][0]['original_price'],
  1269. 'sell_price' => $goods_info['item_list'][0]['sell_price'],
  1270. 'num' => $v['num'],
  1271. ];
  1272. }
  1273. //订单金额 = 商品金额 + 运费
  1274. $order_money = bcadd($price_goods,$price_express ,2);
  1275. if($order_money < 0) $this->exception('订单金额有误');
  1276. $order_insert['price_total'] = $order_money;
  1277. $order_insert['price_goods'] = $price_goods;
  1278. $order_insert['price_express'] = $price_express;
  1279. $order_insert['original_total'] = $original_total ;
  1280. $order_insert['source'] = 3 ;
  1281. $order_info = GoodsOrder::create($order_insert);// 生成订单
  1282. array_walk($order_item,function (&$v,$k)use ($order_info){
  1283. $v['order_id'] = $order_info->id;
  1284. });
  1285. (new GoodsOrderItem())->insertAll($order_item);// 生成订单商品详情
  1286. // 申请开票
  1287. if($order_money > 0 && !empty($bill_info)){
  1288. $ret_val = UserSynth::buildBillApply($this->user_id, $order_info->id,2,$bill_info,0,1,$bill_info['remark'],0);
  1289. if($ret_val['code'] != 200) $this->exception($ret_val['msg']);
  1290. }
  1291. Db::commit();
  1292. }catch (\Exception $e) {
  1293. $this->is_commit = false;
  1294. $this->ret_msg = $e->getMessage();
  1295. Db::rollback();
  1296. }
  1297. $this->is_commit ? $this->success('添加成功',['order_id'=>$order_info->id]):$this->error($this->ret_msg);
  1298. }
  1299. }