ShopOrderController.php 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442
  1. <?php
  2. namespace App\Http\Controllers\Api;
  3. use App\Jobs\Shop\ShopOrderDeliverInfoManage;
  4. use App\Lib\WeApp\WeApp;
  5. use App\Models\Shop\WxShopContact;
  6. use App\Models\Shop\WxShopGoods;
  7. use App\Models\Shop\WxShopOrderCoupon;
  8. use App\Models\Used\WxUsedGood;
  9. use App\Wen\Utils\ApiUtils;
  10. use App\Wen\Utils\GatewayUtils;
  11. use App\Wen\Utils\Settings;
  12. use App\Wen\Utils\ShopUtils;
  13. use App\Wen\Utils\UserUtils;
  14. use App\Wen\Utils\Utils;
  15. use App\Wen\WeixinPay\WeixinPay;
  16. use App\Http\Controllers\Api\Traits\PayTrait;
  17. use App\Models\Shop\WxShopAddress;
  18. use App\Models\Shop\WxShopCart;
  19. use App\Models\Shop\WxShopGoodsProduct;
  20. use App\Models\Shop\WxShopOrder;
  21. use App\Models\Shop\WxShopOrderAfter;
  22. use App\Models\Shop\WxShopOrderGoods;
  23. use App\Models\User\WxUser;
  24. use Carbon\Carbon;
  25. use Illuminate\Http\Request;
  26. use Illuminate\Support\Facades\Cache;
  27. use Illuminate\Support\Facades\DB;
  28. class ShopOrderController extends BaseController
  29. {
  30. use PayTrait;
  31. /**
  32. * 小程序SHOP下单地址
  33. * @param Request $request
  34. * @return \Illuminate\Http\JsonResponse
  35. */
  36. public function order(Request $request)
  37. {
  38. // todo
  39. // if(env('APP_URL') == 'https://mini.minisns.cn'){
  40. // return $this->fail(700003, [], '暂时请私下和群主联系');
  41. // }
  42. $uid = $request->uid;
  43. $r = $this->_create_order($request);
  44. if($r['code'] != 200){
  45. return $this->fail($r['code'], _array_key($r, 'data', []), $r['msg']);
  46. }
  47. //支付需要资料
  48. $openid = WxUser::where('id', $uid)->value('weixin_openid');
  49. $appid = Settings::get('app_id');
  50. $mch_id = Settings::get('mch_id');
  51. $key = Settings::get('mch_secret');
  52. $out_trade_no = $r['orderSn'];
  53. $body = Settings::get('app_title') . 'SHOP购物';
  54. $total_fee = $r['order_amount'];
  55. if(_empty_($openid)){
  56. return $this->fail(200043, [
  57. 'title' => '未绑定微信',
  58. 'content' => '还没有获取到您的小程序openId,无法拉起支付',
  59. 'confirmText' => '去绑定',
  60. 'target_type' => 6,
  61. 'target_id' => '/pagesA/mine/editmine/accountbind'
  62. ], '未绑定微信');
  63. }
  64. return $this->payHandler($uid, 'wxpay', 'mini', $total_fee, $body, $out_trade_no, 2);
  65. // // 发起支付
  66. // $payObject = new WeixinPay($appid, $openid, $mch_id, $key, $out_trade_no, $body, $total_fee);
  67. // $pay_result = $payObject->pay();
  68. // if(_array_key($pay_result, 'return_code', '') == 'FAIL'){
  69. // return $this->fail(200014, [], $pay_result['return_msg']);
  70. // }else{
  71. // return $this->success($pay_result);
  72. // }
  73. }
  74. /** app商品统一下单地址
  75. * @param Request $request
  76. */
  77. public function orderForApp(Request $request){
  78. if(!in_array($request->provider, ['wxpay', 'alipay'])){
  79. return $this->fail(200004, ['msg'=>'provider参数仅支持wxpay/alipay']);
  80. }
  81. if(!in_array($request->pay_type, ['app', 'h5', 'yi', 'code', 'code_pc'])){
  82. return $this->fail(200004, ['msg'=>'pay_type参数仅支持app/h5/yi/code']);
  83. }
  84. $uid = $request->uid;
  85. $r = $this->_create_order($request);
  86. if($r['code'] != 200){
  87. return $this->fail($r['code'], _array_key($r, 'data', []), $r['msg']);
  88. }
  89. // 共同的资料
  90. $total_fee = $r['order_amount'];
  91. $body = Settings::get('app_title') . 'SHOP购物';
  92. $out_trade_no = $r['orderSn'];
  93. $pay_type = $request->pay_type;
  94. global $__MINI_GLOBAL_DEVICE__;
  95. if($__MINI_GLOBAL_DEVICE__ == 'h5' && _empty_default_($request->h5_browser, '') == 'wxclient'){
  96. $pay_type = 'mp';
  97. }
  98. return $this->payHandler($uid, $request->provider, $pay_type, $total_fee, $body, $out_trade_no, 2);
  99. }
  100. private function _create_order(Request $request){
  101. DB::beginTransaction();
  102. try {
  103. $r = ['code'=>0,'msg'=>'', 'orderSn'=>'', 'order_amount'=>0, 'orderId'=>0];
  104. $uid = $request->uid;
  105. $aid = $request->aid;
  106. $user_remark = $request->user_remark;
  107. $goods_amount = $request->goods_amount;
  108. $discounts_amount = $request->discounts_amount;
  109. $order_amount = $request->order_amount;
  110. $order_goods = $request->order_goods;
  111. $random_str_ = _empty_default_($request->random_str_, '');
  112. // 用于检验程序
  113. $buy_user = WxUser::where('id', $uid)->first();
  114. if (_empty_($buy_user) || _empty_($order_goods)) {
  115. DB::rollBack();
  116. $r['code'] = 200001;
  117. return $r;
  118. }
  119. $is_vip = $buy_user->is_member;
  120. $acculate_amount = 0;
  121. $acculate_vip_amount = 0;
  122. $seller_user_id = null;
  123. // 0:电商 6:二手 7: 组局
  124. $order_from = 0;
  125. $contact_id = 0;
  126. $order_goods_id = [];
  127. $goods_type_arr = [];
  128. foreach ($order_goods as $order_good){
  129. $goods_type_arr[] = $order_good['goods_type'];
  130. if($order_good['goods_type'] == 6){
  131. // 闲置
  132. $the_used_good = WxUsedGood::where('id', $order_good['goods_id'])->where('status', 1)->first();
  133. if($the_used_good){
  134. $order_from = 6;
  135. $seller_user_id = $the_used_good->user_id;
  136. $order_goods_id[] = $the_used_good->id;
  137. if($the_used_good->price != $order_good['price']){
  138. DB::rollBack();
  139. $r['code'] = 200004;
  140. $r['msg'] = '参数1检验失败,疑似参数被纂改';
  141. return $r;
  142. }else{
  143. $acculate_amount += ($the_used_good->price * 1);
  144. $acculate_vip_amount += ($the_used_good->price * 1);
  145. }
  146. }else{
  147. DB::rollBack();
  148. $r['code'] = 200003;
  149. $r['msg'] = '订单中存在已售出的闲置商品';
  150. return $r;
  151. }
  152. }else {
  153. $the_product = WxShopGoodsProduct::where([['id', '=', $order_good['product_id']], ['goods_id', '=', $order_good['goods_id']], ['state', '=', 0]])->first();
  154. if ($the_product) {
  155. if($the_product['stock'] < 1){
  156. DB::rollBack();
  157. $r['code'] = 200004;
  158. $r['msg'] = '规格库存不足';
  159. return $r;
  160. }
  161. if($order_good['goods_type'] == 5){
  162. $WxShopGoods = WxShopGoods::where('id', $the_product->goods_id)->first();
  163. $contact_id = $WxShopGoods->contact_id;
  164. }
  165. if ($the_product->price != $order_good['price'] || $the_product->vip_price != $order_good['vip_price']) {
  166. DB::rollBack();
  167. $r['code'] = 200004;
  168. $r['msg'] = '参数1检验失败,疑似参数被纂改';
  169. return $r;
  170. } else {
  171. $order_goods_id[] = $the_product->goods_id;
  172. $product_seller = WxShopGoods::where('id', $the_product->goods_id)->value('user_id');
  173. if(_empty_($seller_user_id)){
  174. $seller_user_id = $product_seller;
  175. }else{
  176. if($seller_user_id == $product_seller){
  177. }else{
  178. $seller_user_id = null;
  179. }
  180. }
  181. $acculate_amount += ($the_product->price * $order_good['num']);
  182. $acculate_vip_amount += ($the_product->vip_price * $order_good['num']);
  183. }
  184. } else {
  185. DB::rollBack();
  186. $r['code'] = 200003;
  187. return $r;
  188. }
  189. }
  190. }
  191. if(in_array(2, $goods_type_arr) || in_array(3, $goods_type_arr) || in_array(4, $goods_type_arr)){
  192. if(count(array_unique($goods_type_arr)) > 1){
  193. DB::rollBack();
  194. $r['code'] = 200004;
  195. $r['msg'] = '虚拟,卡密商品不能和其他商品一起购买';
  196. return $r;
  197. }
  198. }
  199. $acculate_order_amount = $is_vip ? $acculate_vip_amount : $acculate_amount;
  200. if(_abs($acculate_order_amount - $order_amount) >= 0.5 || _abs(($acculate_amount - $acculate_order_amount) - $discounts_amount) >= 0.5){
  201. DB::rollBack();
  202. $r['code'] = 200004;
  203. $r['msg'] = '参数2检验失败,疑似参数被纂改';
  204. return $r;
  205. }
  206. // 纠正前端数据
  207. $acculate_amount = round($acculate_amount, 2);
  208. $acculate_vip_amount = round($acculate_vip_amount, 2);
  209. $goods_amount = $acculate_amount;
  210. $discounts_amount = $is_vip ? round($acculate_amount - $acculate_vip_amount, 2) : 0;
  211. $order_amount = $is_vip ? $acculate_vip_amount : $acculate_amount;
  212. $orderSn = Utils::getSn(1);//生成订单号
  213. if($contact_id > 0 && _empty_($aid)){
  214. $addsinfo = [
  215. 'id' => 0,
  216. 'name' => '',
  217. 'mobile' => '',
  218. 'province' => '',
  219. 'city' => '',
  220. 'county' => '',
  221. 'adds' => '',
  222. ];
  223. }else{
  224. $addsinfo = WxShopAddress::where('user_id', $uid)->where('id', $aid)->first();//获取配送地址
  225. if(!$addsinfo){
  226. DB::rollBack();
  227. $r['code'] = 800003;
  228. return $r;
  229. }
  230. }
  231. //生成SHOP订单
  232. $order_model = new WxShopOrder();
  233. $order_model->user_id = $uid;
  234. $order_model->order_id = $orderSn;//订单号
  235. $order_model->goods_amount = $goods_amount;//商品总价
  236. $order_model->discounts_amount = $discounts_amount;//优惠金额
  237. $order_model->order_amount = $order_amount;//订单总额
  238. $order_model->adds_id = $addsinfo['id'];//收货地址id
  239. $order_model->adds_name = $addsinfo['name'];//收货人姓名
  240. $order_model->adds_mobile = $addsinfo['mobile'];//收货人电话
  241. $order_model->address = $addsinfo['province'] . $addsinfo['city'] . $addsinfo['county'] . $addsinfo['adds'];//收货详细地址
  242. $order_model->contact_id = $contact_id;
  243. $order_model->user_remark = $user_remark;//用户备注
  244. $order_model->pay_status = 1;//支付状态 1=未付款 2=已付款 3=已退款
  245. $order_model->status = 0;//发货状态 0=正常 1=未发货 2=已发货 3=确认收货 4=已退货 5=取消
  246. $order_model->order_from = $order_from;
  247. $order_model->order_goods_id = $order_goods_id;
  248. if($seller_user_id > 0){
  249. // todo: 多商户这里需要拆订单
  250. $order_model->seller_user_id = $seller_user_id;
  251. }
  252. $order_model->save();
  253. $orderId = $order_model->id;//获取订单id
  254. //
  255. $_goods_amount = 0;
  256. $_order_amount = 0;
  257. //批量添加订单商品
  258. $orderGoods = [];
  259. foreach ($order_goods as $k => $v) {
  260. if($v['goods_type'] == 6){
  261. $the_used_good = WxUsedGood::where('id', $v['goods_id'])->where('status', 1)->first();
  262. if ($the_used_good) {
  263. // 临时暂用
  264. WxUsedGood::where('id', $v['goods_id'])->where('status', 1)->update(['status' => 7]);
  265. if($the_used_good->image_urls){
  266. $the_used_good->pic = _array_key($the_used_good->image_urls[0], 'url', '') . '';
  267. }
  268. $created_at = date('Y-m-d H:i:s', time());
  269. $good_servers = [2];
  270. $refund_deadline = Carbon::now()->addDays(7);
  271. if(in_array(1, $good_servers)){
  272. $refund_deadline = Carbon::now();
  273. $created_at = $refund_deadline;
  274. }
  275. $recharge = $the_used_good->price * 1;
  276. $_order_amount += $recharge;
  277. $_goods_amount += $the_used_good->price * 1;
  278. $orderGoods[$k]['pic'] = $the_used_good->pic;
  279. $orderGoods[$k]['name'] = $the_used_good->title;
  280. $orderGoods[$k]['product'] = '';
  281. $orderGoods[$k]['vip_price'] = $the_used_good->price;
  282. $orderGoods[$k]['price'] = $the_used_good->price;
  283. $orderGoods[$k]['recharge'] = $recharge;
  284. $orderGoods[$k]['quantity'] = 1;
  285. $orderGoods[$k]['order_id'] = $orderId;
  286. $orderGoods[$k]['seller_user_id'] = $the_used_good->user_id;
  287. $orderGoods[$k]['buyer_user_id'] = $uid;
  288. $orderGoods[$k]['goods_id'] = $the_used_good->id;
  289. $orderGoods[$k]['goods_type'] = 6;
  290. $orderGoods[$k]['product_id'] = 0;
  291. $orderGoods[$k]['created_at'] = $created_at;
  292. $orderGoods[$k]['refund_deadline'] = $refund_deadline;
  293. }else{
  294. DB::rollBack();
  295. $r['code'] = 200003;
  296. return $r;
  297. }
  298. }else {
  299. $the_product = WxShopGoodsProduct::where('id', $v['product_id'])->first();
  300. // 规格存在并且有存量时
  301. if ($the_product) {
  302. $WxShopGoods = WxShopGoods::where('id', $the_product->goods_id)->first();
  303. $good_servers = $WxShopGoods->service_id;
  304. if (_empty_($good_servers)) {
  305. $good_servers = '[]';
  306. }
  307. $created_at = date('Y-m-d H:i:s', time());
  308. $good_servers = json_decode($good_servers, true);
  309. $refund_deadline = Carbon::now()->addDays(7);
  310. if (in_array(1, $good_servers)) {
  311. $refund_deadline = Carbon::now();
  312. $created_at = $refund_deadline;
  313. }
  314. $recharge = $is_vip ? $the_product->vip_price * $v['num'] : $the_product->price * $v['num'];
  315. $_order_amount += $recharge;
  316. $_goods_amount += $the_product->price * $v['num'];
  317. $orderGoods[$k]['pic'] = $the_product->pic;
  318. $orderGoods[$k]['name'] = $v['goods_name'];
  319. $orderGoods[$k]['product'] = $the_product->param_value;
  320. $orderGoods[$k]['vip_price'] = $the_product->vip_price;
  321. $orderGoods[$k]['price'] = $the_product->price;
  322. $orderGoods[$k]['recharge'] = $recharge;
  323. $orderGoods[$k]['quantity'] = $v['num'];
  324. $orderGoods[$k]['order_id'] = $orderId;
  325. $orderGoods[$k]['seller_user_id'] = $WxShopGoods->user_id ?: 0;
  326. $orderGoods[$k]['buyer_user_id'] = $uid;
  327. $orderGoods[$k]['goods_id'] = $the_product->goods_id;
  328. $orderGoods[$k]['goods_type'] = $WxShopGoods->type;
  329. $orderGoods[$k]['product_id'] = $the_product->id;
  330. $orderGoods[$k]['created_at'] = $created_at;
  331. $orderGoods[$k]['refund_deadline'] = $refund_deadline;
  332. } else {
  333. DB::rollBack();
  334. $r['code'] = 200003;
  335. return $r;
  336. }
  337. }
  338. }
  339. $ogModel = new WxShopOrderGoods();
  340. $ogModel->addAll($orderGoods);
  341. //修改购物车数据
  342. if(_empty_default_($request->cart_id, 0) > 0){
  343. WxShopCart::where('id', _empty_default_($request->cart_id, 0))->update(['state' => 2]);
  344. }else{
  345. WxShopCart::where('user_id', $uid)->where('is_check', 1)->where('state', 0)->update(['state' => 2]);
  346. }
  347. if($random_str_){
  348. Cache::put(md5('shop:order:random:'.$random_str_), $orderId, 60);
  349. }
  350. DB::commit();
  351. $r['code'] = 200;
  352. $r['orderSn'] = $orderSn;
  353. $r['order_amount'] = $order_amount;
  354. $r['orderId'] = $orderId;
  355. return $r;
  356. } catch (\Exception $e) {
  357. DB::rollBack();
  358. _logger_(__file__, __line__, $e->getMessage());
  359. $r['code'] = 200002;
  360. return $r;
  361. }
  362. }
  363. /**
  364. * Shop订单列表Count
  365. */
  366. public function getOrderCount(Request $request)
  367. {
  368. $uid = $request->uid;
  369. $seller = _empty_default_($request->seller, 0);
  370. return $this->success(ShopUtils::get_order_count($uid, $seller == 1));
  371. }
  372. /**
  373. * Shop订单列表
  374. */
  375. public function getOrderList(Request $request)
  376. {
  377. $uid = $request->uid;
  378. $type = $request->type;
  379. $seller = _empty_default_($request->seller, 0);
  380. $yesterday = date("Y-m-d H:i:s", strtotime("-2 hours"));
  381. //清除超时未支付订单
  382. WxShopOrder::where('user_id', $uid)->where('pay_status', 1)->where('status', 0)
  383. ->where('created_at', '<', $yesterday)
  384. ->update(['status' => 5]);
  385. if($seller == 1){
  386. if ($type == 1) {
  387. $data = WxShopOrder::where('seller_user_id', $uid)
  388. ->where('pay_status', 1)->where('status', 0)
  389. ->orderBy('created_at', 'desc')
  390. ->paginate(6);
  391. } else if ($type == 2) {
  392. $data = WxShopOrder::where('seller_user_id', $uid)
  393. ->where('pay_status', 2)->where('status', 1)
  394. ->orderBy('created_at', 'desc')
  395. ->paginate(6);
  396. } else if ($type == 3) {
  397. $data = WxShopOrder::where('seller_user_id', $uid)
  398. ->where('pay_status', 2)->where('status', 2)
  399. ->orderBy('created_at', 'desc')
  400. ->paginate(6);
  401. } else if ($type == 4) {
  402. // 退款中
  403. $order_ids = WxShopOrderGoods::select('order_id')->whereIn('state', [1,2])->whereIn('order_id', function ($query) use($uid){
  404. $query->select('id')->from('wx_shop_order')->where('seller_user_id', $uid)->whereIn('status', [1, 2, 7]);
  405. })->distinct()->pluck('order_id')->toArray();
  406. $data = WxShopOrder::whereIn('id', $order_ids)
  407. ->orderBy('created_at', 'desc')
  408. ->paginate(6);
  409. } else {
  410. if(UserUtils::is_mini_supder_admin($uid)){
  411. $data = WxShopOrder::whereIn('seller_user_id', [$uid, 0])
  412. ->where('status', '<>', 6)
  413. ->orderBy('created_at', 'desc')
  414. ->paginate(6);
  415. }else{
  416. $data = WxShopOrder::where('seller_user_id', $uid)
  417. ->where('status', '<>', 6)
  418. ->orderBy('created_at', 'desc')
  419. ->paginate(6);
  420. }
  421. }
  422. $data->map(function ($v) {
  423. $v->goods = WxShopOrderGoods::where('order_id', $v->id)->get();
  424. $has_refund_good = false;
  425. $face_to_face = 0;
  426. if($v->status == 8){
  427. ShopOrderDeliverInfoManage::dispatch('query', $v->id, null);
  428. }else if($v->status == 10){
  429. ShopOrderDeliverInfoManage::dispatch('virtual-query', $v->id, null);
  430. }else if($v->status == 9){
  431. ShopOrderDeliverInfoManage::dispatch('virtual-upload', $v->id, null);
  432. }
  433. if($v->goods){
  434. $v->goods->map(function ($good, $k) use (&$has_refund_good, &$face_to_face){
  435. if($good->state == 1 || $good->state == 2){
  436. $has_refund_good = true;
  437. }
  438. if($good->goods_type == 6){
  439. if(WxUsedGood::where('id', $good->goods_id)->value('is_self_pickup') == 1){
  440. $face_to_face = 1;
  441. }
  442. }else if($good->goods_type == 5){
  443. $face_to_face = 2;
  444. }else if($good->goods_type == 7){
  445. $face_to_face = 3;
  446. }
  447. return $good;
  448. });
  449. }
  450. if($face_to_face > 0){
  451. $order_coupon = WxShopOrderCoupon::where('order_id', $v->id)->first();
  452. if($order_coupon && $order_coupon->scanner > 0){
  453. $order_coupon->scan_user = UserUtils::get_cached_user($order_coupon->scanner);
  454. $v->order_coupon = $order_coupon;
  455. }
  456. }
  457. // 全部退款中就是7,这个表达商品列表中是否有退款中商品
  458. $v->has_refund = $has_refund_good ? 1 : 0;
  459. // 支持面对面 0:不支持 1:二手的支持 2:核销的支持 3: 组局的核销
  460. $v->face_to_face = $face_to_face > 0 ? $face_to_face : 0;
  461. $v->status_text = self::orderStatusText($v->pay_status, $v->status);
  462. });
  463. return $this->success($data);
  464. }else{
  465. if ($type == 1) {
  466. $data = WxShopOrder::where('user_id', $uid)
  467. ->where('pay_status', 1)->where('status', 0)
  468. ->orderBy('created_at', 'desc')
  469. ->paginate(6);
  470. } else if ($type == 2) {
  471. $data = WxShopOrder::where('user_id', $uid)
  472. ->where('pay_status', 2)->where('status', 1)
  473. ->orderBy('created_at', 'desc')
  474. ->paginate(6);
  475. } else if ($type == 3) {
  476. $data = WxShopOrder::where('user_id', $uid)
  477. ->where('pay_status', 2)->where('status', 2)
  478. ->orderBy('created_at', 'desc')
  479. ->paginate(6);
  480. } else if ($type == 4) {
  481. $data = WxShopOrder::where('user_id', $uid)
  482. ->where('pay_status', 2)->where('status', 3)
  483. ->orderBy('created_at', 'desc')
  484. ->paginate(6);
  485. } else {
  486. $data = WxShopOrder::where('user_id', $uid)
  487. ->where('status', '<>', 6)
  488. ->orderBy('created_at', 'desc')
  489. ->paginate(6);
  490. }
  491. $data->map(function ($v) {
  492. $v->goods = WxShopOrderGoods::where('order_id', $v->id)->get();
  493. $has_refund_good = false;
  494. $face_to_face = 0;
  495. if($v->goods){
  496. $v->goods->map(function ($good, $k) use (&$has_refund_good, &$face_to_face){
  497. if($good->state == 1 || $good->state == 2){
  498. $has_refund_good = true;
  499. }
  500. if($good->goods_type == 6){
  501. if(WxUsedGood::where('id', $good->goods_id)->value('is_self_pickup') == 1){
  502. $face_to_face = 1;
  503. }
  504. }else if($good->goods_type == 5){
  505. $face_to_face = 2;
  506. }else if($good->goods_type == 7){
  507. $face_to_face = 3;
  508. }
  509. return $good;
  510. });
  511. }
  512. // 全部退款中就是7,这个表达商品列表中是否有退款中商品
  513. $v->has_refund = $has_refund_good ? 1 : 0;
  514. // 支持面对面 0:不支持 1:二手的支持 2:核销的支持 3:组局的核销
  515. $v->face_to_face = $face_to_face > 0 ? $face_to_face : 0;
  516. $v->status_text = self::orderStatusText($v->pay_status, $v->status);
  517. });
  518. return $this->success($data);
  519. }
  520. }
  521. /**
  522. * 订单状态
  523. * @param $pay_status
  524. * @param $status
  525. */
  526. public static function orderStatusText($pay_status, $status)
  527. {
  528. $text = '';
  529. if ($pay_status == 1 && $status == 0) {
  530. $text = '待支付(2分钟内有效)';
  531. } else if ($pay_status == 2 && $status == 1) {
  532. $text = '待发货';
  533. } else if ($pay_status == 2 && $status == 2) {
  534. $text = '待收货';
  535. } else if ($pay_status == 2 && $status == 3) {
  536. $text = '待晒单';
  537. } else if ($pay_status == 1 && $status == 5) {
  538. $text = '已取消';
  539. } else if ($pay_status == 3 && $status == 4) {
  540. $text = '已退款';
  541. } else if ($pay_status == 2) {
  542. if($status == 8){
  543. $text = '待收货';
  544. }else if($status == 9){
  545. $text = '待发货';
  546. }else if($status == 10){
  547. $text = '需微信收货';
  548. }
  549. }
  550. return $text;
  551. }
  552. /**
  553. * Shop删除订单
  554. */
  555. public function delOrder(Request $request)
  556. {
  557. $uid = $request->uid;
  558. $oid = $request->oid;
  559. $r = WxShopOrder::where('user_id', $uid)->where('id', $oid)->whereIn('status', [5, 4, 3])
  560. ->update(['status' => 6]);
  561. if($r){
  562. return $this->success();
  563. }
  564. return $this->fail(200004);
  565. }
  566. /**
  567. * Shop取消订单
  568. */
  569. public function cancelOrder(Request $request)
  570. {
  571. $uid = $request->uid;
  572. $oid = $request->oid;
  573. $random_str_ = _empty_default_($request->random_str_, '');
  574. if(_empty_($oid)){
  575. if(!_empty_($random_str_)){
  576. $oid = Cache::get(md5('shop:order:random:'.$random_str_));
  577. }
  578. }
  579. if(_empty_($oid)){
  580. return $this->fail(200001);
  581. }
  582. DB::beginTransaction();
  583. try {
  584. if(WxShopOrder::where('user_id', $uid)->where('id', $oid)->where('pay_status', 1)->where('status', 0)->exists()){
  585. // todo:
  586. WxShopOrderGoods::where('order_id', $oid)->get()->map(function ($v2){
  587. // 库存返还 $rows = ->delete();
  588. if($v2->goods_type == 6){
  589. // 二手
  590. WxUsedGood::where('id', $v2->goods_id)->where('status', 7)->update([
  591. 'status' => 1
  592. ]);
  593. }else{
  594. WxShopGoodsProduct::where('id', $v2->product_id)->where('state', 0)->increment('stock', (int)($v2->quantity));
  595. }
  596. });
  597. WxShopOrder::where('user_id', $uid)->where('id', $oid)->update(['status' => 5]);
  598. DB::commit();
  599. return $this->success();
  600. }
  601. DB::rollBack();
  602. return $this->fail(200000);
  603. } catch (\Exception $e) {
  604. DB::rollBack();
  605. _logger_(__file__, __line__, $e->getMessage());
  606. return $this->fail(200002);
  607. }
  608. }
  609. /**
  610. * Shop重新付款
  611. */
  612. public function payment(Request $request)
  613. {
  614. $uid = $request->uid;
  615. $openid = WxUser::where('id', $uid)->value('weixin_openid');
  616. $appid = Settings::get('app_id');
  617. $mch_id = Settings::get('mch_id');
  618. $key = Settings::get('mch_secret');
  619. $out_trade_no = $request->orderSn;
  620. $body = Settings::get('app_title').'SHOP购物';
  621. $total_fee = $request->order_amount;
  622. return $this->payHandler($uid, 'wxpay', 'mini', $total_fee, $body, $out_trade_no, 2);
  623. // $payObject = new WeixinPay($appid, $openid, $mch_id, $key, $out_trade_no, $body, $total_fee);
  624. // $pay_result = $payObject->pay();
  625. // if(_array_key($pay_result, 'return_code', '') == 'FAIL'){
  626. // return $this->fail(200014, [], $pay_result['return_msg']);
  627. // }else{
  628. // return $this->success($pay_result);
  629. // }
  630. }
  631. /**
  632. * App Shop重新付款
  633. */
  634. public function paymentForApp(Request $request)
  635. {
  636. if(!in_array($request->provider, ['wxpay', 'alipay'])){
  637. return $this->fail(200004, ['msg'=>'provider参数仅支持wxpay/alipay']);
  638. }
  639. if(!in_array($request->pay_type, ['app', 'h5', 'yi', 'code', 'code_pc'])){
  640. return $this->fail(200004, ['msg'=>'pay_type参数仅支持app/h5/yi/code']);
  641. }
  642. $uid = $request->uid;
  643. $out_trade_no = $request->orderSn;
  644. $total_fee = $request->order_amount;
  645. $body = Settings::get('app_title').'SHOP购物';
  646. $pay_type = $request->pay_type;
  647. global $__MINI_GLOBAL_DEVICE__;
  648. if($__MINI_GLOBAL_DEVICE__ == 'h5' && _empty_default_($request->h5_browser, '') == 'wxclient'){
  649. $pay_type = 'mp';
  650. }
  651. return $this->payHandler($uid, $request->provider, $pay_type, $total_fee, $body, $out_trade_no, 2);
  652. }
  653. /**
  654. * 查询物流
  655. * @param Request $request
  656. * @param $no 快递单号
  657. * @return \Illuminate\Http\JsonResponse
  658. */
  659. public function kuaidi(Request $request)
  660. {
  661. $no = $request->no;//快递单号
  662. $type = _empty_default_($request->type, '');
  663. $appcode = Settings::get('app_ali_wuliu_appcode');//换成你自己阿里云的appcode
  664. if(_empty_($no) || _empty_($appcode)){
  665. return $this->fail(200001);
  666. }
  667. $formData = ['no'=>$no];
  668. if(!_empty_($type)){
  669. $formData['type'] = $type;
  670. if($type == 'SFEXPRESS'){
  671. $adds_mobile = WxShopOrder::where('express_no', $no)->where('express_type', $type)->value('adds_mobile');
  672. if($adds_mobile){
  673. $no .= ':'.substr($adds_mobile, -4);
  674. $formData['no'] = $no;
  675. }
  676. }
  677. }else{
  678. $shop_order = WxShopOrder::where('express_no', $no)->first();
  679. if($shop_order){
  680. $express_type = $shop_order->express_type;
  681. $formData['type'] = $express_type;
  682. if($express_type == 'SFEXPRESS'){
  683. $adds_mobile = $shop_order->adds_mobile;
  684. if($adds_mobile){
  685. $no .= ':'.substr($adds_mobile, -4);
  686. $formData['no'] = $no;
  687. }
  688. }
  689. }
  690. }
  691. $res = ApiUtils::ali_request($appcode, 'https://wuliu.market.alicloudapi.com/kdi', $formData);
  692. if($res){
  693. if($res && $res['status'] == 0){
  694. return $this->success($res['result']);
  695. }
  696. }
  697. if($res === null){
  698. UserUtils::assistant_notice('admin', '【阿里全国快递物流查询】Api不可用,是不是服务没开通');
  699. _logger_(__file__, __line__, '【阿里全国快递物流查询】Api不可用,是不是服务没开通');
  700. }
  701. return $this->fail(200003, [], $data['msg'] ?? '暂时未查询到该订单');
  702. }
  703. public function deliver(Request $request){
  704. $uid = $request->uid;
  705. $action = _empty_default_($request->action, 'express');
  706. if(!in_array($action, ['express', 'coupon'])){
  707. return $this->fail(200004);
  708. }
  709. $remark = _empty_default_($request->remark, '');
  710. if($action == 'express'){
  711. $order_id = _empty_default_($request->order_id, 0);
  712. if(_empty_($order_id)){
  713. return $this->fail(200001);
  714. }
  715. $WxOrder = WxShopOrder::find($order_id);
  716. if(!$WxOrder){
  717. return $this->fail(200003);
  718. }
  719. if($WxOrder->seller_user_id != $uid && !UserUtils::is_mini_supder_admin($uid)){
  720. return $this->fail(200000);
  721. }
  722. if($WxOrder->pay_status != 2 || $WxOrder->status != 1){
  723. return $this->fail(200004, [], '该订单已不是待发货状态');
  724. }
  725. $express_type = _empty_default_($request->express_type, '');
  726. $express_no = _empty_default_($request->express_no, '');
  727. if(_empty_($express_type) || _empty_($express_no)){
  728. return $this->fail(200001);
  729. }
  730. $express = '';
  731. $express_arr = ShopUtils::get_expree_name_range();
  732. foreach ($express_arr as $item){
  733. if($item['type'] == $express_type){
  734. $express = $item['name'];
  735. break;
  736. }
  737. }
  738. if(_empty_($express)){
  739. return $this->fail(200004, [], '未查找到该快递公司');
  740. }
  741. $remark = strip_tags($remark);
  742. if(_empty_($remark)){
  743. $remark = '';
  744. }
  745. // 验证express_no是否可用
  746. $flag = true;
  747. if(!$flag){
  748. $appcode = Settings::get('app_ali_wuliu_appcode');//换成你自己阿里云的appcode
  749. if(_empty_($appcode)){
  750. return $this->fail(200001, [], '管理员未配置阿里物流查询接口');
  751. }
  752. // 顺丰特殊情况
  753. if(_empty_($express_type)){
  754. $shop_order = WxShopOrder::where('express_no', $express_no)->first();
  755. if($shop_order){
  756. $express_type = $shop_order->express_type;
  757. if($express_type == 'SFEXPRESS'){
  758. $adds_mobile = $shop_order->adds_mobile;
  759. if($adds_mobile){
  760. $express_no .= ':'.substr($adds_mobile, -4);
  761. }
  762. }
  763. }
  764. }else{
  765. if($express_type == 'SFEXPRESS'){
  766. $adds_mobile = WxShopOrder::where('express_no', $express_no)->where('express_type', $express_type)->value('adds_mobile');
  767. if($adds_mobile){
  768. $express_no .= ':'.substr($adds_mobile, -4);
  769. }
  770. }
  771. }
  772. $res = ApiUtils::ali_request($appcode, 'https://wuliu.market.alicloudapi.com/kdi', ['no'=>$express_no, 'type' => $express_type ]);
  773. if($res){
  774. if($res && $res['status'] == 0){
  775. $flag = true;
  776. }else{
  777. return $this->fail(200004, [], $res['msg']);
  778. }
  779. }
  780. if(!$flag){
  781. return $this->fail(200004, [], '未查找到物流信息');
  782. }
  783. }
  784. DB::beginTransaction();
  785. try {
  786. // todo:
  787. $ship_at = date('Y-m-d H:i:s', time());
  788. WxShopOrder::where('id', $order_id)->update([
  789. 'express' => $express,
  790. 'express_no' => $express_no,
  791. 'express_type' => $express_type,
  792. 'remark' => $remark,
  793. 'ship_at' => $ship_at,
  794. 'status' => 2,
  795. ]);
  796. $oinfo = WxShopOrder::where('id', $order_id)->first();
  797. $nr = '您的订单:' . $oinfo['order_id'] . ' 由:' . $express . ':「<a href="/pagesA/shop/logistics/logistics?nu='.$express_no.'&type='.$express_type.'">' . $express_no . '</a>」已经发出了。';
  798. // 发送通知
  799. UserUtils::add_user_notice(6001, $oinfo['user_id'], '商品发货通知', $nr, 100, '', $order_id);
  800. // 处理售后的催货
  801. WxShopOrderAfter::where([
  802. ['order_id', '=', $oinfo['order_id']],
  803. ['title', '=', '催发货']
  804. ])->update([
  805. 'state' => 1,
  806. ]);
  807. Cache::forget('total:todo:count');
  808. Cache::forget('total:tenant:todo:count');
  809. GatewayUtils::success(GatewayUtils::uid2client_id($uid), 17);
  810. GatewayUtils::success(GatewayUtils::uid2client_id($WxOrder->user_id), 17);
  811. GatewayUtils::success(GatewayUtils::uid2client_id($WxOrder->user_id), 12);
  812. DB::commit();
  813. return $this->success([
  814. 'express_no' => $express_no,
  815. 'express_type' => $express_type,
  816. ]);
  817. } catch (\Exception $e) {
  818. DB::rollBack();
  819. _logger_(__file__, __line__, $e->getMessage());
  820. return $this->fail(200006);
  821. }
  822. }else if($action == 'coupon'){
  823. $code = _empty_default_($request->code, '');
  824. $code = str_replace(' ', '', $code);
  825. if(_empty_($code)){
  826. return $this->fail(200001);
  827. }
  828. $coupon = WxShopOrderCoupon::where('code', $code)->first();
  829. if(!$coupon){
  830. return $this->fail(200003);
  831. }
  832. if($coupon->status !== 0){
  833. return $this->fail(200010, [], '该扫码卷已不可使用');
  834. }
  835. $order_id = $coupon->order_id;
  836. $WxOrder = WxShopOrder::find($order_id);
  837. if(!$WxOrder){
  838. return $this->fail(200003);
  839. }
  840. if($WxOrder->pay_status != 2 || $WxOrder->status != 1){
  841. return $this->fail(200004, [], '订单不是已支付和待发货状态');
  842. }
  843. $order_goods = WxShopOrderGoods::where('order_id', $WxOrder->id)->where('state', 0)->get()->toArray();
  844. if(_empty_($order_goods)){
  845. return $this->fail(200010, [], '参数错误');
  846. }
  847. $scanners = [];
  848. if($WxOrder->order_from === 0){
  849. $goods_id = $order_goods[0]['goods_id'];
  850. $scanners = WxShopGoods::where('id', $goods_id)->value('scanners');
  851. $is_in_scanners = false;
  852. if($scanners){
  853. if(is_string($scanners)){
  854. $scanners = explode(',', $scanners);
  855. }
  856. }
  857. }
  858. if(_empty_($scanners)){
  859. $scanners = [];
  860. }
  861. if(in_array($uid, $scanners)){
  862. $is_in_scanners = true;
  863. }
  864. if($WxOrder->seller_user_id != $uid && !UserUtils::is_mini_supder_admin($uid) && !$is_in_scanners){
  865. return $this->fail(200000, [], '您不是该订单的核销人');
  866. }
  867. if($WxOrder->pay_status != 2 || $WxOrder->status != 1){
  868. return $this->fail(200004, [], '该订单已不是待发货状态');
  869. }
  870. $shopOrder = WxShopOrder::where('id', $order_id)->first();
  871. // 先检查是否需要对接发货信息管理
  872. $is_need_deliver_info_manage = false;
  873. if($shopOrder->serial_platform === 0 && $shopOrder->serial_platform_type == 'mini' && Settings::get('need_mini_deliver_info_manage', 0) == 1){
  874. $is_need_deliver_info_manage = true;
  875. }
  876. if($is_need_deliver_info_manage){
  877. $weapp = new WeApp('mini');
  878. $manage = $weapp->getDeliverInfoManage();
  879. $manage->selfPickUp($WxOrder, $uid);
  880. return $this->fail(200047, [ 'query_state_no' => ('wx_shoporder_' . $shopOrder->serial_number) ]);
  881. }else{
  882. if(ShopUtils::coupon_to_finish($shopOrder, $uid, '')){
  883. GatewayUtils::success(GatewayUtils::uid2client_id($uid), 17);
  884. GatewayUtils::success(GatewayUtils::uid2client_id($WxOrder->user_id), 17);
  885. return $this->success();
  886. }else{
  887. return $this->fail(200006);
  888. }
  889. }
  890. }
  891. }
  892. /**
  893. * Shop催发货
  894. */
  895. public function pushDelivery(Request $request)
  896. {
  897. $uid = $request->uid;
  898. // 长id
  899. $on = $request->on;
  900. $title = $request->title;
  901. $message = $request->message;
  902. $used_goods_id = [];
  903. // 自营
  904. $system_shop_goods_id = [];
  905. // 短id
  906. $wxShopOrder = WxShopOrder::where('order_id', $on)->first();
  907. if(_empty_($wxShopOrder)){
  908. return $this->fail(200003);
  909. }
  910. $the_order_id = $wxShopOrder->id;
  911. WxShopOrderGoods::where('order_id', $the_order_id)->get()->map(function ($v) use (&$used_goods_id, &$system_shop_goods_id){
  912. if($v->goods_type == 6){
  913. $used_goods_id[] = $v->goods_id;
  914. }else{
  915. $system_shop_goods_id[] = $v->goods_id;
  916. }
  917. });
  918. if($used_goods_id){
  919. foreach ($used_goods_id as $used_id){
  920. $WxUsedGood = WxUsedGood::find($used_id);
  921. $user_id = $WxUsedGood->user_id;
  922. UserUtils::assistant_notice($user_id, '您的闲置商品(<a href="/pagesU/used-mall/detail/index?id='.$WxUsedGood->id.'">id: '.$WxUsedGood->id.'</a>)订单被催发货了,请您和购买者协商,达成一致的发货的时间约定');
  923. }
  924. return $this->success();
  925. }
  926. if($system_shop_goods_id){
  927. $isExists = WxShopOrderAfter::where('user_id', $uid)->where('order_id', $on)->where('state', 0)->exists();
  928. if ($isExists) {
  929. return $this->fail(800010);
  930. } else {
  931. $model = new WxShopOrderAfter();
  932. $model->user_id = $uid;
  933. $model->seller_user_id = $wxShopOrder->user_id;
  934. $model->order_id = $on;
  935. $model->title = $title;
  936. $model->content = $message;
  937. $model->save();
  938. return $this->success();
  939. }
  940. }
  941. }
  942. /** 扫码劵
  943. * @param Request $request
  944. */
  945. public function orderCoupon(Request $request){
  946. $uid = $request->uid;
  947. $action = _empty_default_($request->action, 'get');
  948. if(!in_array($action, ['get'])){
  949. return $this->fail(200001);
  950. }
  951. $order_id = _empty_default_($request->order_id, 0);
  952. if(_empty_($order_id)){
  953. return $this->fail(200001);
  954. }
  955. $order = WxShopOrder::where([
  956. ['id', '=', $order_id],
  957. ['user_id', '=', $uid],
  958. ['pay_status', '=', 2],
  959. // ['status', '=', 1]
  960. ])->first();
  961. if(!$order){
  962. return $this->fail(200004, [], '当前订单不是已支付状态,无法获得扫码卷');
  963. }
  964. if($action == 'get'){
  965. $coupon = ShopUtils::get_user_coupon($uid, $order_id);
  966. $goods = WxShopOrderGoods::where('order_id', $order_id)->get();
  967. $order_title = '';
  968. $order_image = '';
  969. $is_used = false;
  970. if($goods){
  971. $goods->map(function ($v, $k) use (&$order_title, &$order_image, &$is_used, &$order){
  972. if(!_empty_($order_title)){
  973. $order_title .= '、';
  974. }
  975. $order_title .= $v->name;
  976. if(_empty_($order_image)){
  977. $order_image = $v->pic;
  978. }
  979. if($v->goods_type == 6){
  980. $is_used = true;
  981. $user_good = WxUsedGood::find($v->goods_id);
  982. if($user_good->distance && $user_good->distance > 0){
  983. if($user_good->distance < 10){
  984. $user_good->distance = '<10m';
  985. $user_good->distance_name = $user_good->district;
  986. }else if($user_good->distance >= 1000 && $user_good->distance <= 200000){
  987. $user_good->distance = '<'. round($user_good->distance / 1000, 2).'km';
  988. $user_good->distance_name = $user_good->city;
  989. }else if($user_good->distance > 200000){
  990. $user_good->distance = round($user_good->distance / 1000, 2).'km';
  991. $user_good->distance_name = $user_good->province;
  992. }else{
  993. $user_good->distance = '<'.(int)$user_good->distance.'m';
  994. $user_good->distance_name = $user_good->district;
  995. }
  996. }else{
  997. $user_good->distance = '';
  998. $user_good->distance_name = $user_good->district;
  999. }
  1000. if(_empty_($user_good->distance_name)){
  1001. $user_good->distance_name = '';
  1002. }
  1003. $order->distance = $user_good->distance;
  1004. $order->longitude = $user_good->longitude;
  1005. $order->latitude = $user_good->latitude;
  1006. $order->address_name = $user_good->address_name;
  1007. $order->address_detailed = $user_good->address_detailed;
  1008. }else if($v->goods_type == 5 || $v->goods_type == 7){
  1009. $shop_contact = WxShopContact::find($order->contact_id);
  1010. if(!$shop_contact){
  1011. _logger_(__file__, __line__, 'shop_contact id为'.$order->contact_id.'不存在');
  1012. }
  1013. $order->distance = '';
  1014. $order->longitude = $shop_contact->longitude;
  1015. $order->latitude = $shop_contact->latitude;
  1016. $order->address_name = $shop_contact->address_name;
  1017. $order->address_detailed = $shop_contact->address_detail;
  1018. if($shop_contact->phone){
  1019. $order->seller_phone = $shop_contact->phone;
  1020. }
  1021. }
  1022. // 状态(0正常,1退款中,2退货退款,3已退款,4异常)
  1023. if($v->state == 1){
  1024. $v->state_tip = '退款中';
  1025. }else if($v->state == 2){
  1026. $v->state_tip = '退货退款';
  1027. }else if($v->state == 3){
  1028. $v->state_tip = '已退款';
  1029. } else if($v->state == 4){
  1030. $v->state_tip = '异常';
  1031. } else if($v->state == 5){
  1032. $v->state_tip = '微信退款处理中';
  1033. } else if($v->state == 6){
  1034. $v->state_tip = '支付宝退款处理中';
  1035. }else{
  1036. if($v->refund_deadline === 0){
  1037. $v->state_tip = '不支持退款';
  1038. }else if($v->refund_deadline == 1){
  1039. $v->state_tip = '申请退款';
  1040. }else{
  1041. $v->state_tip = '超时不可退款';
  1042. }
  1043. }
  1044. });
  1045. }
  1046. $order->address_tip = ($order->distance ? ('距您'.$order->distance. ' · ') : '') . $order->address_name;
  1047. $order->order_title = $order_title;
  1048. $order->order_image = $order_image;
  1049. $order->is_used = $is_used;
  1050. if(_empty_($order->seller_phone)){
  1051. $order->seller_phone = $order->seller_user_id > 0 ? _get_origin_attribute('wx_user', [['id', '=', $order->seller_user_id]], 'phone') : '';
  1052. }
  1053. $order->query_state_no = 'wx_shoporder_' . $order->serial_number;
  1054. return $this->success([
  1055. 'order' => $order,
  1056. 'coupon' => $coupon,
  1057. 'goods' => $goods
  1058. ]);
  1059. }
  1060. }
  1061. /**
  1062. * Shop申请退款
  1063. */
  1064. public function orderRefund(Request $request)
  1065. {
  1066. $uid = $request->uid;
  1067. $action = _empty_default_($request->action, 'add');
  1068. // todo: 这是订单的某个规格的退款, 还有一种情况是整个订单的退款
  1069. if($action == 'add'){
  1070. // 申请退款
  1071. // 1、根据某个订单的product_id做定位
  1072. $oid = $request->oid;
  1073. $opid = $request->opid;
  1074. // 2、直接根据orderGood id做定位
  1075. $order_good_id = $request->order_good_id;
  1076. if($order_good_id > 0){
  1077. $oginfo = WxShopOrderGoods::where('buyer_user_id', $uid)->where('id', $order_good_id)->first();
  1078. }else{
  1079. $oginfo = WxShopOrderGoods::where('buyer_user_id', $uid)->where('order_id', $oid)->where('product_id', $opid)->first();
  1080. }
  1081. if(_empty_($oginfo)){
  1082. return $this->fail(200003);
  1083. }
  1084. if($oginfo->refund_deadline == 0){
  1085. return $this->fail(200009, [], '该商品不支持退款');
  1086. }
  1087. if($oginfo->refund_deadline == 2){
  1088. return $this->fail(200009, [], '您已超过最大可退款期限');
  1089. }
  1090. $shopOrder = WxShopOrder::where('id', $oginfo['order_id'])->first();
  1091. if(_empty_($shopOrder)){
  1092. return $this->fail(200003);
  1093. }
  1094. $title = '退款申请';
  1095. $message = '订单:'.$shopOrder['order_id'].':'.$oginfo['quantity'].'件 '.$oginfo['name'].'【'.$oginfo['product'].'】会员价为:【'.$oginfo['vip_price'].'】普通价为:'.$oginfo['price'].' 申请退款。';
  1096. if( $oginfo->goods_type != 2 && $oginfo->goods_type != 3 ){
  1097. DB::beginTransaction();
  1098. try {
  1099. // todo:
  1100. WxShopOrderGoods::where('order_id', $oid)->where('product_id', $opid)
  1101. ->update(['state' => 1]);
  1102. $model = new WxShopOrderAfter();
  1103. $model->user_id = $uid;
  1104. $model->seller_user_id = $oginfo->seller_user_id ?: 0;
  1105. $model->order_id = $shopOrder['order_id'];
  1106. $model->title = $title;
  1107. $model->content = $message;
  1108. $model->save();
  1109. $order_id = $oginfo->order_id;
  1110. if(!WxShopOrderGoods::where('order_id', $order_id)->where('state', 0)->exists()){
  1111. update_shop_order_meta($order_id, 'last_status', WxShopOrder::where('id', $order_id)->value('status'), 'n');
  1112. WxShopOrder::where('id', $order_id)->update([
  1113. 'status' => 7
  1114. ]);
  1115. }
  1116. DB::commit();
  1117. return $this->success([], 200, '退款申请提交成功,我们会尽快为您处理。');
  1118. } catch (\Exception $e) {
  1119. DB::rollBack();
  1120. _logger_(__file__, __line__, $e->getMessage());
  1121. return $this->fail(200006);
  1122. }
  1123. }
  1124. return $this->fail(200004, [], '虚拟物品不能申请退款');
  1125. }else if($action == 'confirm' || $action == 'cancel'){
  1126. // 同意退款
  1127. $order_good_id = _empty_default_($request->order_good_id, 0);
  1128. if(_empty_($order_good_id)){
  1129. return $this->fail(200001);
  1130. }
  1131. $orderGood = WxShopOrderGoods::find($order_good_id);
  1132. if(_empty_($orderGood)){
  1133. return $this->fail(200003);
  1134. }
  1135. $old_state = $orderGood->state;
  1136. if($old_state != 1 && $old_state != 2){
  1137. return $this->fail(200004, [], '该订单商品状态不是退款中');
  1138. }
  1139. $order_id = $orderGood->order_id;
  1140. $seller_user_id = WxShopOrder::where('id', $order_id)->value('seller_user_id');
  1141. if(_empty_($seller_user_id)){
  1142. return $this->fail(200000);
  1143. }
  1144. if($seller_user_id != $uid){
  1145. return $this->fail(200000, [], '你不是该次订单的卖家');
  1146. }
  1147. if($action == 'confirm'){
  1148. $r = ShopUtils::order_good_refund($order_good_id);
  1149. if($r){
  1150. return $this->success();
  1151. }else{
  1152. return $this->fail(200006);
  1153. }
  1154. }else{
  1155. DB::beginTransaction();
  1156. try {
  1157. // todo:
  1158. if($old_state != 3){
  1159. // 这里仅仅再判断一次,已无必要
  1160. WxShopOrderGoods::where('id', $order_good_id)->update([
  1161. 'state' => 0,
  1162. ]);
  1163. $last_status = get_shop_order_meta($order_id, 'last_status', 'n');
  1164. if(_empty_($last_status, true)){
  1165. $last_status = 1;
  1166. }
  1167. update_shop_order_meta($order_id, 'last_status', null, 'n');
  1168. WxShopOrder::where('id', $order_id)->update(['status' => $last_status]);
  1169. DB::commit();
  1170. return $this->success();
  1171. }
  1172. DB::rollBack();
  1173. return $this->fail(200006);
  1174. } catch (\Exception $e) {
  1175. DB::rollBack();
  1176. _logger_(__file__, __line__, $e->getMessage());
  1177. return $this->fail(200006);
  1178. }
  1179. }
  1180. }
  1181. }
  1182. /**
  1183. * Shop退货退款
  1184. */
  1185. public function refundGoods(Request $request)
  1186. {
  1187. $uid = $request->uid;
  1188. $on = $request->on;
  1189. $oid = $request->oid;
  1190. $opid = $request->opid;
  1191. $title = $request->title;
  1192. $message = $request->message;
  1193. $oginfo = WxShopOrderGoods::where('order_id', $oid)->where('product_id', $opid)->first();
  1194. if(_empty_($oginfo)){
  1195. return $this->fail(200003);
  1196. }
  1197. if($oginfo->refund_deadline == 0){
  1198. return $this->fail(200009, [], '该商品不支持退款');
  1199. }
  1200. if($oginfo->refund_deadline == 2){
  1201. return $this->fail(200009, [], '您已超过最大可退款期限');
  1202. }
  1203. if( $oginfo->goods_type != 2 && $oginfo->goods_type != 3 ){
  1204. WxShopOrderGoods::where('order_id', $oid)->where('product_id', $opid)
  1205. ->update(['state' => 2]);
  1206. $model = new WxShopOrderAfter();
  1207. $model->user_id = $uid;
  1208. $model->seller_user_id = $oginfo->seller_user_id ?: 0;
  1209. $model->order_id = $on;
  1210. $model->title = $title;
  1211. $model->content = $message;
  1212. $model->save();
  1213. $nr = '您购买的:「' . $oginfo['name'] . '(规格:' . $oginfo['product'] . ')」×' . $oginfo['quantity'] . '件的售后申请已提交,您需要联系客服将货物退回。';
  1214. UserUtils::add_user_notice(6002, $uid, '商品售后通知', $nr, 100);
  1215. return $this->success();
  1216. }
  1217. return $this->fail(200004, [], '虚拟物品不能申请退货退款');
  1218. }
  1219. public function shop_order_process(Request $request) {
  1220. $type = _empty_default_($request->type, '');
  1221. if ($type == 'update_user_remark') {
  1222. return $this->user_remark($request);
  1223. }
  1224. }
  1225. private function user_remark(Request &$request){
  1226. $uid = $request->uid;
  1227. $order_id = _empty_default_($request->order_id, 0);
  1228. $user_remark = _empty_default_($request->user_remark, '');
  1229. if(_empty_($order_id) || _empty_($user_remark)){
  1230. return $this->fail(200001);
  1231. }
  1232. if(is_array($user_remark)){
  1233. $user_remark = json_encode($user_remark);
  1234. }
  1235. $shop_order = WxShopOrder::find($order_id);
  1236. if(!$shop_order){
  1237. return $this->fail(200003);
  1238. }
  1239. if($shop_order->status != 1){
  1240. return $this->fail(200004, [], '当前订单状态不支持修改');
  1241. }
  1242. if($shop_order->user_id != $uid && !UserUtils::is_mini_supder_admin($uid)){
  1243. return $this->fail(200004, [], '当前订单不是你的订单,无法修改');
  1244. }
  1245. WxShopOrder::where('id', $order_id)->where('user_id', $uid)->update([
  1246. 'user_remark' => $user_remark
  1247. ]);
  1248. return $this->success();
  1249. }
  1250. /**
  1251. * Shop确认收货
  1252. */
  1253. public function confirmReceipt(Request $request)
  1254. {
  1255. $uid = $request->uid;
  1256. $oid = $request->oid;
  1257. if(_empty_($uid) || _empty_($oid)){
  1258. return $this->fail(200001);
  1259. }
  1260. $shop_order = WxShopOrder::where([
  1261. ['id', '=', $oid],
  1262. ['user_id', '=', $uid],
  1263. ['status', '=', 2],
  1264. ['pay_status', '=', 2]
  1265. ])->first();
  1266. if($shop_order){
  1267. if(ShopUtils::confirm_recived($shop_order, 1)){
  1268. return $this->success();
  1269. }else{
  1270. return $this->fail(200006);
  1271. }
  1272. }else{
  1273. return $this->fail(200003);
  1274. }
  1275. }
  1276. }