Orders.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. <?php namespace App\Http\Controllers\Api;
  2. use App\Http\Controllers\Api\Api;
  3. use App\Models\Orders as Model;
  4. use App\Models\Product;
  5. use App\Models\Product\Skus as ProductSkus;
  6. use App\Http\Requests\Api\Orders as Request;
  7. use App\Models\Business;
  8. use App\Models\City;
  9. use App\Models\Custom;
  10. use App\Models\CustomAddr;
  11. use App\Models\CustomCoupon;
  12. use App\Models\CustomScore;
  13. use App\Models\OrdersAddr;
  14. use App\Models\OrdersProduct;
  15. use App\Models\ShopCart;
  16. use Illuminate\Support\Facades\DB;
  17. use App\Models\WeiBan\Tags as WeiBanTags;
  18. /**
  19. * 订单接口
  20. *
  21. * @author 刘相欣
  22. *
  23. * */
  24. class Orders extends Api{
  25. /**
  26. * 创建订单 /api/orders/create
  27. *
  28. * */
  29. public function create(Request $request,Custom $Custom,City $City,Model $Model,WeiBanTags $WeiBanTags,OrdersAddr $OrdersAddr,OrdersProduct $OrdersProduct,Product $Product,ProductSkus $ProductSkus,CustomCoupon $CustomCoupon,ShopCart $ShopCart,CustomAddr $CustomAddr,CustomScore $CustomScore){
  30. // 接口验签
  31. // $this->verify_sign();
  32. // 验证参数
  33. $request->scene('create')->validate();
  34. // 检查登录
  35. $uid = $this->checkLogin();
  36. // 接收参数
  37. $isCart = request('is_cart',0);
  38. $productList = request('product_list','[]');
  39. $customCouponId = request('custom_coupon_id',0);
  40. $addrId = request('addr_id',0);
  41. // 如果不存在数据
  42. if( !$addrId ) return json_send(['code'=>'error','msg'=>'请选择收货地址','data'=>['error'=>'请选择收货地址']]);
  43. // 解码购买信息
  44. $buyList = json_decode($productList,true);
  45. // 如果不存在数据
  46. if( empty($buyList) ) return json_send(['code'=>'error','msg'=>'没有需下单的产品','data'=>['error'=>'产品列表为空']]);
  47. // 选择地址
  48. $addr = $CustomAddr->getOne($addrId);
  49. // 如果不存在数据
  50. if( !$addr ) return json_send(['code'=>'error','msg'=>'地址有误,请核对','data'=>['error'=>'没有找到对应的地址']]);
  51. // 重组数据
  52. $addr = ['contact_name'=>$addr['contact_name'],'contact_shop'=>$addr['contact_shop'],'contact_phone'=>$addr['contact_phone'],'contact_province'=>$addr['contact_province'],'contact_city'=>$addr['contact_city'],'contact_area'=>$addr['contact_area'],'contact_addr'=>$addr['contact_addr']];
  53. // 获取客户城市ID
  54. $custom = $Custom->getOne($uid);
  55. // 如果不存在的话
  56. if( !$custom ) return json_send(['code'=>'no_login','msg'=>'用户不存在,请重新登录','data'=>['error'=>'用户不存在,请重新登录']]);
  57. // 如果不存在的话
  58. if( !$custom['city_id'] ) return json_send(['code'=>'error','msg'=>'请选择所在城市后下单','data'=>['error'=>'请选择所在城市后下单']]);
  59. // 获取城市ID
  60. $cityId = $custom['city_id'];
  61. $cityName = $City->getOne($cityId,'name');
  62. $pid = $City->getOne($cityId,'pid');
  63. $province = $City->getOne($pid,'name');
  64. // 判断选择的城市名称是不是一致
  65. if( $cityName != $addr['contact_city'] ) return json_send(['code'=>'error','msg'=>'收货地址请选择'.$province.'/'.$cityName,'data'=>['error'=>'收货地址需与您所选城市一致']]);
  66. // 商品购买数量
  67. $buyNum = [];
  68. // 循环购买信息
  69. foreach ($buyList as $key => $value) {
  70. // 获取每个商品的总量
  71. $buyNum[$value['product_id']] = isset($buyNum[$value['product_id']]) ? ($buyNum[$value['product_id']] + $value['buy_num']) : $value['buy_num'];
  72. }
  73. // 查询用户标签
  74. $tags = $WeiBanTags->getListByWeibanExtid($custom['weiban_extid']);
  75. // 查询产品信息
  76. $productList = $Product->getListByIds(array_column($buyList,'product_id'));
  77. $skusList = $ProductSkus->getListByIds(array_column($buyList,'product_skuid'));
  78. // 当前时间
  79. $time = time();
  80. // 产品以商业公司分组,方便写入订单
  81. $orderProduct = [];
  82. // 产品价格同级,用于优惠券计算
  83. $productPrice = [];
  84. // 循环处理购买信息
  85. foreach ($buyList as $buyInfo) {
  86. // 如果产品不存在
  87. if( empty($productList[$buyInfo['product_id']]) ) return json_send(['code'=>'error','msg'=>'产品不存在或已下架','data'=>['error'=>'产品不存在或已下架=>'.$buyInfo['product_id']]]);
  88. // 获取产信息
  89. $productInfo = $productList[$buyInfo['product_id']];
  90. // 判断是不是可以参与
  91. if( $productInfo['tag_scope'] ) {
  92. // 解析数组
  93. $productInfo['tag_scope'] = explode(',',$productInfo['tag_scope']);
  94. // 标签范围限定时,默认不能参与
  95. $allowJoin = 0;
  96. // 判断标签是不是存在
  97. foreach ($tags as $value) {
  98. // 标签范围内,允许参加
  99. if( in_array($value['name'],$productInfo['tag_scope']) ) $allowJoin = 1;
  100. }
  101. // 如果不能参与
  102. if( !$allowJoin ) return json_send(['code'=>'error','msg'=>'不在 '.$productInfo['product_name'].' 参与范围','data'=>['error'=>'不在标签范围内']]);
  103. }
  104. // 判断是不是可以参与
  105. if( $productInfo['tag_exclude'] ) {
  106. // 解析数组
  107. $productInfo['tag_exclude'] = explode(',',$productInfo['tag_exclude']);
  108. // 判断标签是不是存在
  109. foreach ($tags as $value) {
  110. // 标签排除范围内,不允许参加
  111. if( in_array($value['name'],$productInfo['tag_exclude']) ) return json_send(['code'=>'error','msg'=>'不在 '.$productInfo['product_name'].' 可参与范围','data'=>['error'=>'用户在标签排除范围']]);
  112. }
  113. }
  114. // 如果产品限购
  115. if( $productInfo['quota'] ) {
  116. // 是否在限购时间,当前时间大于开始时间,并且小于结束时间
  117. if( $productInfo['quota_start'] <= $time && $time <= $productInfo['quota_end'] ){
  118. // 通过时间查询商品的购买总数
  119. $total = $OrdersProduct->query()->where([['custom_uid','=',$uid],['product_id','=',$productInfo['id']],['insert_time','>=',$productInfo['quota_start']],['insert_time','<=',$productInfo['quota_end']]])->sum('buy_num');
  120. // 判断限购数量
  121. $total = $buyNum[$buyInfo['product_id']] + $total;
  122. // 如果超过数量
  123. if( $total > $productInfo['quota'] ) return json_send(['code'=>'error','msg'=>'限购'.$productInfo['quota'].'套-'.$productInfo['product_name'],'data'=>['error'=>'已超限=>'.($total - $productInfo['quota'])]]);
  124. }
  125. }
  126. // 如果存在SKU
  127. if( $buyInfo['product_skuid'] ) {
  128. // 判断SKU信息存不存在
  129. if( empty($skusList[$buyInfo['product_skuid']]) ) return json_send(['code'=>'error','msg'=>'该产品规格不存在或已下架','data'=>['error'=>'SKU不存在或已下架=>'.$buyInfo['product_skuid']]]);
  130. // 产品ID不匹配的话
  131. if( $skusList[$buyInfo['product_skuid']]['product_id'] != $buyInfo['product_id'] ) return json_send(['code'=>'error','msg'=>'该产品规格不存在或已下架','data'=>['error'=>'SKU不匹配=>'.$buyInfo['product_skuid']]]);
  132. // 如果SKU存在,合并产品信息
  133. $productInfo = array_merge($productInfo,$skusList[$buyInfo['product_skuid']]);
  134. // 需要扣除的库存
  135. $skusList[$buyInfo['product_skuid']]['decr'] = empty($skusList[$buyInfo['product_skuid']]['decr']) ? $buyInfo['buy_num'] : $skusList[$buyInfo['product_skuid']]['decr'] + $buyInfo['buy_num'];
  136. }
  137. // 需要扣除的库存
  138. $productList[$buyInfo['product_id']]['decr'] = empty($productList[$buyInfo['product_id']]['decr']) ? $buyInfo['buy_num'] : $productList[$buyInfo['product_id']]['decr'] + $buyInfo['buy_num'];
  139. // 判断库存
  140. if( $productInfo['stock'] < $productList[$buyInfo['product_id']]['decr'] ) return json_send(['code'=>'error','msg'=>$productInfo['product_name'].'-库存不足','data'=>['error'=>'产品库存不足=>'.$buyInfo['product_id']]]);
  141. // 计算价值
  142. $priceTotal = $buyInfo['buy_num'] * $productInfo['price'];
  143. // 购买信息
  144. $buyInfo = ['is_rebate'=>0,'custom_uid'=>$uid,'business_id'=>$productInfo['business_id'],'product_id'=>$buyInfo['product_id'],'buy_num'=>$buyInfo['buy_num'],'price_total'=>$priceTotal,'pay_total'=>$priceTotal,'coupon_total'=>0,'product_name'=>$productInfo['product_name'],'sku_attr_names'=>$productInfo['sku_attr_names'],'product_thumb'=>$productInfo['product_thumb']];
  145. // 获取信息
  146. if( !isset($orderProduct[$buyInfo['business_id']]) ) $orderProduct[$buyInfo['business_id']] = ['business_id'=>$buyInfo['business_id'],'custom_uid'=>$buyInfo['custom_uid'],'price_total'=>0,'pay_total'=>0,'coupon_total'=>0,'product_list'=>[]];
  147. // 订单产品
  148. $orderProduct[$buyInfo['business_id']]['price_total'] += $buyInfo['price_total'];
  149. $orderProduct[$buyInfo['business_id']]['pay_total'] += $buyInfo['price_total'];
  150. $orderProduct[$buyInfo['business_id']]['product_list'][] = $buyInfo;
  151. // 商品优惠信息不存在,创建
  152. if( !isset($productPrice[$buyInfo['product_id']]) ) $productPrice[$buyInfo['product_id']] = ['price_total'=>0,'rebate_price'=>0];
  153. // 计算总价
  154. $productPrice[$buyInfo['product_id']]['price_total'] = $productPrice[$buyInfo['product_id']]['price_total'] + $priceTotal;
  155. }
  156. // 优惠券数据
  157. $couponRebate = $CustomCoupon->getRebatePrice($customCouponId,$uid,$productPrice);
  158. // 判断是否使用了优惠券
  159. $usedCoupon = $couponRebate['is_used'];
  160. // 获取优惠券扣减金额
  161. $productPrice = $couponRebate['product_price'];
  162. // 获取优惠券赠品信息
  163. $rebateProduct = $couponRebate['rebate_product'];
  164. // 组合订单数据
  165. foreach ($orderProduct as $key => $order) {
  166. // 判断哪一家的赠品
  167. if( isset($rebateProduct[$order['business_id']]) ){
  168. // 循环赠品
  169. foreach ( $rebateProduct[$order['business_id']] as $value) {
  170. // 没有对应的产品
  171. if( !isset($productList[$value['product_id']]) ) $productList[$value['product_id']] = ['id'=>$value['id'],'stock'=>$value['stock']];
  172. // 判断库存,如果库存不足,只赠送最后的库存
  173. if( $productList[$value['product_id']]['stock'] <= $value['buy_num'] ) $value['buy_num'] = $productList[$value['product_id']]['stock'];
  174. // 库存扣减
  175. $productList[$value['product_id']]['decr'] = empty($productList[$value['product_id']]['decr']) ? $value['buy_num'] : $productList[$value['product_id']]['decr'] + $value['buy_num'];
  176. // 追加到订单表
  177. $order['product_list'][] = ['is_rebate'=>1,'custom_uid'=>$uid,'business_id'=>$value['business_id'],'product_id'=>$value['product_id'],'buy_num'=>$value['buy_num'],'price_total'=>$value['price_total'],'pay_total'=>$value['pay_total'],'coupon_total'=>$value['coupon_total'],'product_name'=>$value['product_name'],'sku_attr_names'=>$value['sku_attr_names'],'product_thumb'=>$value['product_thumb']];
  178. }
  179. }
  180. // 计算总价格
  181. foreach ($order['product_list'] as $k=>$product) {
  182. // 商品不存在,不进行扣减
  183. if( empty($productPrice[$product['product_id']]['rebate_price']) ) {
  184. // 重组
  185. $order['product_list'][$k] = $product;
  186. continue;
  187. }
  188. // 总优惠增加
  189. $order['coupon_total'] = $order['coupon_total'] + $productPrice[$product['product_id']]['rebate_price'];
  190. // 当前商品的优惠折扣计算
  191. $product['coupon_total'] = number_format( $productPrice[$product['product_id']]['rebate_price'] * ($product['price_total'] / $productPrice[$product['product_id']]['price_total']) , 2 , '.' ,'');
  192. // 成交小计
  193. $product['pay_total'] = $product['pay_total'] - $product['coupon_total'];
  194. // 重组
  195. $order['product_list'][$k] = $product;
  196. }
  197. // 成交总价
  198. $order['pay_total'] = $order['pay_total'] - $order['coupon_total'];
  199. // 赠送积分
  200. $order['order_score'] = (config('order_score_send',0) && floor( $order['pay_total'] * 1 ) > 0 ) ? floor( $order['pay_total'] * 1 ) : 0;
  201. // 成交总价
  202. $order['custom_uid'] = $uid;
  203. // 重组
  204. $orderProduct[$key] = $order;
  205. }
  206. // 组合数据,写入订单表,子表
  207. DB::beginTransaction();
  208. // 写入数据
  209. try {
  210. // 扣减商品库存
  211. foreach ($productList as $key => $value) {
  212. // 扣减库存
  213. $result = $Product->edit($value['id'],['stock'=>DB::raw('stock+-'.$value['decr'])]);
  214. // 判断结果
  215. if( !$result ) {
  216. // 回退数据
  217. DB::rollBack();
  218. // 错误提示
  219. return json_send(['code'=>'error','msg'=>'库存扣减失败','data'=>['error'=>'库存扣减失败']]);
  220. }
  221. }
  222. // 扣减商品库存
  223. foreach ($skusList as $key => $value) {
  224. // 扣减库存
  225. $result = $ProductSkus->edit($value['sku_id'],['stock'=>DB::raw('stock+-'.$value['decr'])]);
  226. // 判断结果
  227. if( !$result ) {
  228. // 回退数据
  229. DB::rollBack();
  230. // 错误提示
  231. return json_send(['code'=>'error','msg'=>'库存扣减失败','data'=>['error'=>'库存扣减失败']]);
  232. }
  233. }
  234. // 循环订单数据
  235. foreach ($orderProduct as $order) {
  236. // 先获取产品列表,并去除key
  237. $productItem = array_values($order['product_list']);
  238. // 删除非必要数据
  239. unset($order['product_list']);
  240. // 创建总订单
  241. $orderId = $Model->add($order);
  242. // 如果订单写入失败
  243. if( !$orderId ) {
  244. // 回退数据
  245. DB::rollBack();
  246. // 错误提示
  247. return json_send(['code'=>'error','msg'=>'下单失败','data'=>['error'=>'订单创建失败']]);
  248. }
  249. // 创建子订单
  250. foreach ($productItem as $key=>$value) {
  251. // 增加订单ID
  252. $value['order_id'] = $orderId;
  253. // 增加订单ID
  254. $value['insert_time']= $time;
  255. $value['update_time']= $time;
  256. // 结果
  257. $productItem[$key] = $value;
  258. }
  259. // 写入子表
  260. $result = $OrdersProduct->query()->insert($productItem);
  261. // 如果扣减失败
  262. if( !$result ) {
  263. // 回退数据
  264. DB::rollBack();
  265. // 提示信息
  266. return json_send(['code'=>'error','msg'=>'子订单创建失败','data'=>['error'=>'子订单创建失败']]);
  267. }
  268. // 写入订单地址表
  269. $addr['order_id'] = $orderId;
  270. // 写入订单地址表
  271. $result = $OrdersAddr->add($addr);
  272. // 地址写入失败
  273. if( !$result ) {
  274. // 回退数据
  275. DB::rollBack();
  276. // 提示信息
  277. return json_send(['code'=>'error','msg'=>'地址写入失败','data'=>['error'=>'地址写入失败']]);
  278. }
  279. // 赠送积分
  280. if( $order['order_score'] > 0 ) $CustomScore->trade($order['custom_uid'],$orderId,$order['order_score'],5,1);
  281. // 如果使用了优惠券
  282. if( $usedCoupon ) $CustomCoupon->edit($usedCoupon,['status'=>1,'order_id'=>$orderId]);
  283. // 购物车
  284. if( $isCart ) $ShopCart->query()->where([['custom_uid','=',$uid]])->whereIn('skuid',array_column($buyList,'product_skuid'))->delete();
  285. }
  286. // 自动发放优惠券
  287. $this->autoCoupon($uid);
  288. // 提交数据
  289. DB::commit();
  290. // 返回结果
  291. return json_send(['code'=>'success','msg'=>'下单成功','data'=>['id'=>null]]);
  292. // 返回结果
  293. } catch (\Throwable $th) {
  294. // 回退数据
  295. DB::rollBack();
  296. // 判断结果,如果库存扣减失败的话
  297. if( stripos($th->getMessage(),'UNSIGNED') ) return json_send(['code'=>'error','msg'=>'库存不足','data'=>['error'=>'产品库存扣减失败']]);
  298. // 下单失败提示
  299. return json_send(['code'=>'error','msg'=>'系统异常,请稍后再试','data'=>['error'=>$th->getMessage().$th->getLine()]]);
  300. }
  301. }
  302. /**
  303. * 获取列表 /api/orders/get_list
  304. *
  305. * @param string $name 产品名称
  306. * @param int $page 页码,默认1
  307. * @param int $limit 每页条数,默认10条
  308. *
  309. * */
  310. public function get_list(Request $request,Model $Model,OrdersProduct $OrdersProduct,Business $Business){
  311. // 接口验签
  312. // $this->verify_sign();
  313. // 验证参数
  314. $request->scene('get_list')->validate();
  315. // 检查登录
  316. $uid = $this->checkLogin();
  317. // 接收参数
  318. $status = request('status',0);
  319. $limit = request('limit',10);
  320. // 显示
  321. $map = [['custom_uid','=',$uid]];
  322. // 查询状态
  323. if( $status ) $map[] = ['status','=',$status];
  324. // 查询
  325. $Paginator = $Model->query()->where($map)->orderByDesc('id')->paginate($limit,['id','pay_total','status','price_total','coupon_total','business_id','pay_total','weizan_orderid','insert_time']);
  326. // 订单产品
  327. $productList = $OrdersProduct->query()->whereIn('order_id', array_column($Paginator->items(),'id'))->select(['id as item_id','order_id','product_id','buy_num','is_rebate','sku_attr_names as product_spec','product_name','product_thumb'])->get()->toArray();
  328. // 循环处理
  329. foreach ($Paginator as $key => $order) {
  330. // 商品列表
  331. $itemList = [];
  332. // 返回结果
  333. foreach ($productList as $item) {
  334. // 产品图路径
  335. $item['product_thumb'] = path_compat($item['product_thumb']);
  336. // 如果是订单的
  337. if( $item['order_id'] == $order['id'] ) $itemList[] = $item;
  338. }
  339. // 获取子列表
  340. $order['state'] = (string) $Model->getState($order['status'],'state');
  341. // 获取子列表
  342. $order['business_name'] = (string) ($order['business_id'] ? $Business->getOne($order['business_id'],'name') : ($order['weizan_orderid'] ? '微赞订单' : ''));
  343. // 获取子列表
  344. $order['contents_class']= 0;
  345. // 获取子列表
  346. $order['product_list'] = $itemList;
  347. // 重组
  348. $Paginator[$key] = $order;
  349. }
  350. // 获取数据
  351. $data['total'] = $Paginator->total();
  352. $data['current_page'] = $Paginator->currentPage();
  353. $data['per_page'] = $Paginator->perPage();
  354. $data['last_page'] = $Paginator->lastPage();
  355. $data['data'] = $Paginator->items();
  356. // 返回结果
  357. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$data]);
  358. }
  359. /**
  360. * 自动发放优惠券
  361. *
  362. */
  363. private function autoCoupon($uid){
  364. // 模型实例
  365. $Rule = new \App\Models\CouponRewardRule();
  366. // 获取配置列表
  367. $ruleList = $Rule->getList();
  368. // 如果没有信息的话
  369. if( !$ruleList ) return ['success'=>'暂无活动'];
  370. // 其他实例
  371. $RuleProduct = new \App\Models\CouponRewardProduct();
  372. $OrdersProduct = new \App\Models\OrdersProduct();
  373. $Custom = new \App\Models\Custom();
  374. $Coupon = new \App\Models\Coupon();
  375. $CustomCoupon = new \App\Models\CustomCoupon();
  376. // 获取客户城市ID
  377. $customCityId = (int) $Custom->getValue($uid,'city_id');
  378. // 循环配置列表
  379. foreach ( $ruleList as $value ) {
  380. // 如果存在城市范围,并且不在城市范围,不参与这个活动
  381. if( $value['city_ids'] && !in_array($customCityId,explode(',',$value['city_ids'])) ) continue;
  382. // 未到开始时间
  383. if( $value['start_time'] > time() ) continue;
  384. // 通过配置ID获取对应的商品范围
  385. $productList = $RuleProduct->getListByRule($value['id']);
  386. // 如果不存在产品范围,跳过
  387. if( !$productList ) continue;
  388. // 获取客户 规定时段内订单的商品ID以及购买数量
  389. $orderList = $OrdersProduct->query()->where([['custom_uid','=',$uid],['status','=',1],['insert_time','>=',$value['start_time']],['insert_time','<=',$value['end_time']]])->get(['product_id','buy_num'])->toArray();
  390. // 如果没有订单总数
  391. if( !$orderList ) continue;
  392. // 计算商品总量
  393. $total = 0;
  394. // 循环商品范围
  395. foreach ($productList as $scope) {
  396. // 循环订单产品
  397. foreach ($orderList as $order) {
  398. // 如果产品不相等
  399. if( $scope['product_id'] != $order['product_id'] ) continue;
  400. // 相等的计算总量
  401. $total += $scope['product_units'] * $order['buy_num'];
  402. }
  403. }
  404. // 判断总数是不是达标
  405. if( $total < $value['std_num'] ) continue;
  406. // 达标的是否已经发送过优惠券
  407. $havaCoupon = $CustomCoupon->query()->where([['custom_uid','=',$uid],['coupon_id','=',$value['coupon_id']]])->first(['status']);
  408. // 已经发过优惠券的,不发
  409. if( $havaCoupon ) continue;
  410. // 获取优惠券的可用时间
  411. $expTime = $Coupon->query()->where([['id','=',$value['coupon_id']]])->value('exp_time');
  412. // 时间转时间
  413. $expTime = $Coupon->getExpTime($expTime);
  414. // 发送优惠券
  415. $CustomCoupon->add(['coupon_id'=>$value['coupon_id'],'custom_uid'=>$uid,'exp_time'=>$expTime]);
  416. }
  417. // 返回成功
  418. return ['success'=>'操作成功'];
  419. }
  420. /**
  421. * 取消 /api/orders/cancel
  422. *
  423. * */
  424. public function cancel( Request $request, Model $Model,OrdersProduct $OrdersProduct,CustomScore $CustomScore){
  425. // 验证参数
  426. $request->scene('cancel')->validate();
  427. // 检查登录
  428. $uid = $this->checkLogin();
  429. // 接收参数
  430. $id = request('id',0);
  431. $status = 4;
  432. // 获取产品和数量
  433. $oldData = $Model->query()->where([['id','=',$id],['custom_uid','=',$uid]])->first(['id','order_score','status','custom_uid','insert_time']);
  434. // 如果用户不存在
  435. if( !$oldData ) return json_send(['code'=>'error','msg'=>'订单不存在']);
  436. // 如果已经取消
  437. if( $oldData['status'] == 4 ) return json_send(['code'=>'error','msg'=>'订单已取消']);
  438. // 组合数据,写入订单表,子表
  439. DB::beginTransaction();
  440. try{
  441. // 查询数据
  442. $result = $Model->setOrderStatus($id,$status,$OrdersProduct);
  443. // 提示新增失败
  444. if( isset($result['error']) ) {
  445. // 回退数据
  446. DB::rollBack();
  447. // 提示信息
  448. return json_send(['code'=>'error','msg'=>$result['error'],'data'=>['error'=>$result['error']]]);
  449. }
  450. if( $status == 4 ){
  451. // 取消积分
  452. if( $oldData['order_score'] > 0 ) {
  453. // 如果扣减失败
  454. $result = $CustomScore->trade($oldData['custom_uid'],$oldData['id'],($oldData['order_score']*-1),6,1);
  455. // 提示新增失败
  456. if( isset($result['error']) ) {
  457. // 回退数据
  458. DB::rollBack();
  459. // 提示信息
  460. return json_send(['code'=>'error','msg'=>'取消赠送积分失败','data'=>['error'=>$result['error']]]);
  461. }
  462. }
  463. // 取消关联订单
  464. $result = $Model->cancelRelate($oldData['insert_time'],$oldData['custom_uid'],$OrdersProduct,$CustomScore);
  465. // 提示新增失败
  466. if( isset($result['error']) ) {
  467. // 回退数据
  468. DB::rollBack();
  469. // 提示信息
  470. return json_send(['code'=>'error','msg'=>'取消关联订单失败','data'=>['error'=>$result['error']]]);
  471. }
  472. }
  473. // 提交数据
  474. DB::commit();
  475. // 告知结果
  476. return json_send(['code'=>'success','msg'=>'取消成功']);
  477. // 返回结果
  478. } catch (\Throwable $th) {
  479. // 回退数据
  480. DB::rollBack();
  481. // 下单失败提示
  482. return json_send(['code'=>'error','msg'=>'取消失败','data'=>['error'=>$th->getMessage().$th->getLine()]]);
  483. }
  484. }
  485. /**
  486. * 获取订单子数据 /api/orders/get_item
  487. *
  488. * @param string $name 产品名称
  489. * @param int $page 页码,默认1
  490. * @param int $limit 每页条数,默认10条
  491. *
  492. * */
  493. public function get_item(Request $request,Model $Model,OrdersProduct $OrdersProduct,Business $Business){
  494. // 接口验签
  495. // $this->verify_sign();
  496. // 验证参数
  497. $request->scene('get_item')->validate();
  498. // 检查登录
  499. $uid = $this->checkLogin();
  500. // 接收参数
  501. $id = request('id',0);
  502. // 查询
  503. $orderInfo = $Model->query()->where([['id','=',$id],['custom_uid','=',$uid]])->first(['id','pay_total','status','price_total','coupon_total','business_id','pay_total','weizan_orderid','insert_time']);
  504. // 如果用户不存在
  505. if( !$orderInfo ) return json_send(['code'=>'error','msg'=>'订单不存在']);
  506. // 转数组
  507. $orderInfo = $orderInfo->toArray();
  508. // 订单产品
  509. $orderInfo['product_list'] = $OrdersProduct->query()->where([['order_id','=',$id]])->select(['id as item_id','order_id','product_id','buy_num','is_rebate','sku_attr_names as product_spec','product_name','product_thumb'])->get()->toArray();
  510. // 循环处理
  511. foreach ($orderInfo['product_list'] as $key => $item) {
  512. // 产品图路径
  513. $item['product_thumb'] = path_compat($item['product_thumb']);
  514. // 重组
  515. $orderInfo['product_list'][$key] = $item;
  516. }
  517. // 获取子列表
  518. $orderInfo['state'] = (string) $Model->getState($orderInfo['status'],'state');
  519. // 获取子列表
  520. $orderInfo['business_name'] = (string) ($orderInfo['business_id'] ? $Business->getOne($orderInfo['business_id'],'name') : ($orderInfo['weizan_orderid'] ? '微赞订单' : ''));
  521. // 返回结果
  522. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$orderInfo]);
  523. }
  524. }