OrderCommon.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 山西牛酷信息科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com.cn
  8. * 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和使用。
  9. * 任何企业和个人不允许对程序代码以任何形式任何目的再发布。
  10. * =========================================================
  11. */
  12. namespace app\model\order;
  13. use addon\coupon\model\Coupon;
  14. use app\model\express\ExpressPackage;
  15. use app\model\goods\Goods;
  16. use app\model\goods\GoodsStock;
  17. use app\model\member\MemberAccount;
  18. use app\model\system\Cron;
  19. use app\model\system\Pay;
  20. use app\model\verify\Verify;
  21. use think\facade\Cache;
  22. use app\model\BaseModel;
  23. use app\model\message\Message;
  24. /**
  25. * 常规订单操作
  26. *
  27. * @author Administrator
  28. *
  29. */
  30. class OrderCommon extends BaseModel
  31. {
  32. /*****************************************************************************************订单基础状态(其他使用)********************************/
  33. // 订单待付款
  34. const ORDER_CREATE = 0;
  35. // 订单已支付
  36. const ORDER_PAY = 1;
  37. // 订单已发货(配货)
  38. const ORDER_DELIVERY = 3;
  39. // 订单已收货
  40. const ORDER_TAKE_DELIVERY = 4;
  41. // 订单已结算完成
  42. const ORDER_COMPLETE = 10;
  43. // 订单已关闭
  44. const ORDER_CLOSE = -1;
  45. /*********************************************************************************订单支付状态****************************************************/
  46. // 待支付
  47. const PAY_WAIT = 0;
  48. // 支付中
  49. const PAY_DOING = 1;
  50. // 已支付
  51. const PAY_FINISH = 2;
  52. /**************************************************************************支付方式************************************************************/
  53. const OFFLINEPAY = 10;
  54. /**
  55. * 基础订单状态(不同类型的订单可以不使用这些状态,但是不能冲突)
  56. * @var unknown
  57. */
  58. public $order_status = [
  59. self::ORDER_CREATE => [
  60. 'status' => self::ORDER_CREATE,
  61. 'name' => '待支付',
  62. 'is_allow_refund' => 0,
  63. 'action' => [
  64. [
  65. 'action' => 'orderClose',
  66. 'title' => '关闭订单',
  67. 'color' => ''
  68. ],
  69. [
  70. 'action' => 'orderAddressUpdate',
  71. 'title' => '修改地址',
  72. 'color' => ''
  73. ],
  74. [
  75. 'action' => 'orderAdjustMoney',
  76. 'title' => '调整价格',
  77. 'color' => ''
  78. ],
  79. ],
  80. 'member_action' => [
  81. [
  82. 'action' => 'orderClose',
  83. 'title' => '关闭订单',
  84. 'color' => ''
  85. ],
  86. [
  87. 'action' => 'orderPay',
  88. 'title' => '支付',
  89. 'color' => ''
  90. ],
  91. ],
  92. 'color' => ''
  93. ],
  94. self::ORDER_PAY => [
  95. 'status' => self::ORDER_PAY,
  96. 'name' => '待发货',
  97. 'is_allow_refund' => 0,
  98. 'action' => [
  99. ],
  100. 'member_action' => [
  101. ],
  102. 'color' => ''
  103. ],
  104. self::ORDER_DELIVERY => [
  105. 'status' => self::ORDER_DELIVERY,
  106. 'name' => '已发货',
  107. 'is_allow_refund' => 1,
  108. 'action' => [
  109. ],
  110. 'member_action' => [
  111. ],
  112. 'color' => ''
  113. ],
  114. self::ORDER_TAKE_DELIVERY => [
  115. 'status' => self::ORDER_TAKE_DELIVERY,
  116. 'name' => '已收货',
  117. 'is_allow_refund' => 1,
  118. 'action' => [
  119. ],
  120. 'member_action' => [
  121. ],
  122. 'color' => ''
  123. ],
  124. self::ORDER_COMPLETE => [
  125. 'status' => self::ORDER_COMPLETE,
  126. 'name' => '已完成',
  127. 'is_allow_refund' => 1,
  128. 'action' => [
  129. ],
  130. 'member_action' => [
  131. ],
  132. 'color' => ''
  133. ],
  134. self::ORDER_CLOSE => [
  135. 'status' => self::ORDER_CLOSE,
  136. 'name' => '已关闭',
  137. 'is_allow_refund' => 0,
  138. 'action' => [
  139. ],
  140. 'member_action' => [
  141. ],
  142. 'color' => ''
  143. ],
  144. ];
  145. /**
  146. * 基础支付方式(不考虑实际在线支付方式或者货到付款方式)
  147. * @var unknown
  148. */
  149. public $pay_type = [
  150. 'ONLINE_PAY' => '在线支付',
  151. 'BALANCE' => '余额支付',
  152. 'OFFLINE_PAY' => '线下支付'
  153. ];
  154. /**
  155. * 订单类型
  156. *
  157. * @var int
  158. */
  159. public $order_type = [
  160. 1 => "普通订单",
  161. 2 => "自提订单",
  162. 3 => "外卖订单",
  163. 4 => "虚拟订单",
  164. ];
  165. /**
  166. * 获取支付方式
  167. */
  168. public function getPayType()
  169. {
  170. //获取订单基础的其他支付方式
  171. $pay_type = $this->pay_type;
  172. //获取当前所有在线支付方式
  173. $onlinepay = event('PayType', []);
  174. if (!empty($onlinepay)) {
  175. foreach ($onlinepay as $k => $v) {
  176. $pay_type[ $v['pay_type'] ] = $v['pay_type_name'];
  177. }
  178. }
  179. return $pay_type;
  180. }
  181. /**
  182. * 订单类型(根据物流配送来区分)
  183. */
  184. public function getOrderTypeStatusList()
  185. {
  186. $list = [];
  187. $list['all'] = array(
  188. "name" => "全部",
  189. "type" => 'all',
  190. "status" => array_column($this->order_status, "name", "status")
  191. );
  192. foreach ($this->order_type as $k => $v) {
  193. switch ($k) {
  194. case 1:
  195. $order_model = new Order();
  196. break;
  197. case 2:
  198. $order_model = new StoreOrder();
  199. break;
  200. case 3:
  201. $order_model = new LocalOrder();
  202. break;
  203. case 4:
  204. $order_model = new VirtualOrder();
  205. break;
  206. }
  207. $item = array(
  208. "name" => $v,
  209. "type" => $k,
  210. "status" => array_column($order_model->order_status, "name", "status")
  211. );
  212. $list[ $k ] = $item;
  213. }
  214. return $list;
  215. }
  216. /**
  217. * 生成订单编号
  218. *
  219. * @param unknown $site_id
  220. */
  221. public function createOrderNo($site_id)
  222. {
  223. $time_str = date('YmdHi');
  224. $num = 0;
  225. $max_no = Cache::get($site_id . "_" . $time_str);
  226. if (!isset($max_no) || empty($max_no)) {
  227. $max_no = 1;
  228. } else {
  229. $max_no = $max_no + 1;
  230. }
  231. $order_no = $time_str . sprintf("%04d", $max_no);
  232. Cache::set($site_id . "_" . $time_str, $max_no);
  233. return $order_no;
  234. }
  235. public function getShopStatSum($site_id,$time){
  236. $condition[] = ['pay_time', '>=', $time];
  237. if($site_id>0) {
  238. $condition[] = ['site_id', '=', $site_id];
  239. }
  240. $stat_shop = model('order')->getInfo([$condition],'COUNT(order_id) count,SUM(shop_money) sum');
  241. return $this->success($stat_shop);
  242. }
  243. public function getStatShop($site_id,$type){
  244. if($type == 1){
  245. $field = 'COUNT(order_id) count,SUM(pay_money) sum';
  246. $time = strtotime('today');
  247. if($site_id>0) {
  248. $condition[] = ['site_id', '=', $site_id];
  249. $field = 'COUNT(order_id) count,SUM(shop_money) sum';
  250. }
  251. $condition[]=['pay_time','>=',$time];
  252. $member_where[]=['reg_time','>=',$time];
  253. $goods_where[]=['create_time','>=',$time];
  254. $stat_shop = model('order')->getInfo([$condition],$field);
  255. $member = model('member')->getInfo([$member_where],'COUNT(member_id) member_count');
  256. $goods = model('goods')->getInfo([$goods_where],'COUNT(goods_id) add_goods_count');
  257. $stat_shop['member_count']=$member['member_count'];
  258. $stat_shop['add_goods_count']=$goods['add_goods_count'];
  259. }
  260. else{
  261. if($site_id>0) {
  262. $condition[] = ['site_id', '=', $site_id];
  263. }
  264. $time = strtotime('yesterday');
  265. $end = $time+86400;
  266. $condition[]=['pay_time','between',[$time,$end]];
  267. $stat_shop = model('order')->getInfo([$condition],'COUNT(order_id) count,SUM(shop_money) sum');
  268. }
  269. return $this->success($stat_shop);
  270. }
  271. /**********************************************************************************订单操作基础方法(订单关闭,订单完成,订单调价)开始********/
  272. /**
  273. * 订单删除
  274. *
  275. * @param unknown $condition
  276. */
  277. public function deleteOrder($condition)
  278. {
  279. $res = model('order')->update([ 'is_delete' => 1 ], $condition);
  280. if ($res === false) {
  281. return $this->error();
  282. } else {
  283. return $this->success($res);
  284. }
  285. }
  286. /**
  287. * @return void
  288. * 订单支付
  289. */
  290. public function order_pay($data){
  291. model('order')->startTrans();
  292. try {
  293. $order_list = model("order")->getList([ [ 'order_id', 'in', $data['order_id'] ] ], '*');
  294. foreach ($order_list as &$v) {
  295. $order_info = ['order_status' => $v['order_status'], 'order_id' => $v['order_id']];
  296. $order_model = new Order();
  297. $order_model->orderPay($order_info, $data["pay_type"]);
  298. }
  299. $member_account_model = new MemberAccount();
  300. $member_account_model->addMemberAccount($data['member_id'], 'balance_money', -$data['pay_money'], 'order', '订单消费', '订单消费');
  301. $goods_model = new Goods();
  302. $order_goods_list = model("order_goods")->getList([ [ 'order_id', 'in', $data['order_id'] ] ], '*');
  303. foreach ($order_goods_list as $ck => $v1) {
  304. $goods_model->incGoodsSaleNum($v1["sku_id"], $v1["num"]);
  305. }
  306. model('order')->commit();
  307. return $this->success();
  308. } catch (\Exception $e) {
  309. model('order')->rollback();
  310. return $this->error('', $e->getMessage());
  311. }
  312. }
  313. /**
  314. * 订单完成
  315. *
  316. * @param int $order_id
  317. */
  318. public function orderComplete($order_id)
  319. {
  320. $cache = Cache::get("order_complete_execute_" . $order_id);
  321. if (empty($cache)) {
  322. Cache::set("order_complete_execute_" . $order_id, 1);
  323. } else {
  324. return $this->success();
  325. }
  326. $lock_result = $this->verifyOrderLock($order_id);
  327. if ($lock_result["code"] < 0)
  328. return $lock_result;
  329. $order_info = model('order')->getInfo([ [ 'order_id', '=', $order_id ] ], 'member_id, order_money, refund_money,order_status');
  330. if ($order_info['order_status'] == self::ORDER_COMPLETE) {
  331. return $this->success();
  332. }
  333. $order_data = array(
  334. 'order_status' => self::ORDER_COMPLETE,
  335. 'order_status_name' => $this->order_status[ self::ORDER_COMPLETE ]["name"],
  336. 'order_status_action' => json_encode($this->order_status[ self::ORDER_COMPLETE ], JSON_UNESCAPED_UNICODE),
  337. 'finish_time' => time(),
  338. 'is_enable_refund' => 0
  339. );
  340. $res = model('order')->update($order_data, [ [ 'order_id', "=", $order_id ] ]);
  341. Cache::set("order_complete_execute_" . $order_id, '');
  342. //修改用户表order_complete_money和order_complete_num
  343. model('member')->setInc([ [ 'member_id', '=', $order_info['member_id'] ] ], 'order_complete_money', $order_info['order_money'] - $order_info['refund_money']);
  344. model('member')->setInc([ [ 'member_id', '=', $order_info['member_id'] ] ], 'order_complete_num');
  345. event('OrderComplete', [ 'order_id' => $order_id ]);
  346. $order_refund_model = new OrderRefund();
  347. //订单项移除可退款操作
  348. $order_refund_model->removeOrderGoodsRefundAction([ [ "order_id", "=", $order_id ] ]);
  349. //订单完成
  350. $message_model = new Message();
  351. $message_model->sendMessage([ 'keywords' => "ORDER_COMPLETE", 'order_id' => $order_id ]);
  352. return $this->success($res);
  353. }
  354. /**
  355. * 订单关闭
  356. * @param int $order_id
  357. */
  358. public function orderClose($order_id)
  359. {
  360. model('order')->startTrans();
  361. try {
  362. $order_info = model("order")->getInfo([ [ "order_id", "=", $order_id ] ], "coupon_id,pay_status,member_id,is_lock,balance_money,order_no,mobile,order_status");
  363. if ($order_info["order_status"] == -1) {
  364. return $this->success();
  365. }
  366. $locak_result = $this->verifyOrderLock($order_info);
  367. if ($locak_result["code"] < 0)
  368. return $locak_result;
  369. $order_data = array(
  370. 'order_status' => self::ORDER_CLOSE,
  371. 'order_status_name' => $this->order_status[ self::ORDER_CLOSE ]["name"],
  372. 'order_status_action' => json_encode($this->order_status[ self::ORDER_CLOSE ], JSON_UNESCAPED_UNICODE),
  373. 'close_time' => time(),
  374. 'is_enable_refund' => 0
  375. );
  376. $res = model('order')->update($order_data, [ [ 'order_id', "=", $order_id ] ]);
  377. //库存处理
  378. $condition = array(
  379. [ "order_id", "=", $order_id ]
  380. );
  381. //循环订单项 依次返还库存
  382. $order_goods_list = model('order_goods')->getList($condition, "sku_id,num,refund_status");
  383. $goods_stock_model = new GoodsStock();
  384. $order_refund_model = new OrderRefund();
  385. $goods_model = new Goods();
  386. $is_exist_refund = false;//是否存在退款
  387. foreach ($order_goods_list as $k => $v) {
  388. //如果是已维权完毕的订单项, 库存不必再次返还
  389. if ($v["refund_status"] != $order_refund_model::REFUND_COMPLETE) {
  390. $item_param = array(
  391. "sku_id" => $v["sku_id"],
  392. "num" => $v["num"],
  393. );
  394. //返还库存
  395. $goods_stock_model->incStock($item_param);
  396. }
  397. if ($v["refund_status"] == $order_refund_model::REFUND_COMPLETE) {
  398. $is_exist_refund = true;
  399. }
  400. //减少商品销量(必须支付过)
  401. if ($order_info["pay_status"] > 0) {
  402. $goods_model->decGoodsSaleNum($v["sku_id"], $v["num"]);
  403. }
  404. }
  405. //订单项移除可退款操作
  406. $order_refund_model->removeOrderGoodsRefundAction([ [ "order_id", "=", $order_id ] ]);
  407. //返还店铺优惠券
  408. $coupon_id = $order_info["coupon_id"];
  409. if ($coupon_id > 0) {
  410. $coupon_model = new Coupon();
  411. $coupon_model->refundCoupon($coupon_id, $order_info["member_id"]);
  412. }
  413. //平台优惠券
  414. //平台余额 退还余额
  415. if (!$is_exist_refund) {//因为订单完成后 只有全部退款完毕订单才会关闭
  416. if ($order_info["balance_money"] > 0) {
  417. $member_account_model = new MemberAccount();
  418. $result = $member_account_model->addMemberAccount($order_info["member_id"], "balance", $order_info["balance_money"], "order", "余额返还", "订单关闭,返还余额:" . $order_info["balance_money"]);
  419. }
  420. }
  421. //订单关闭后操作
  422. event('OrderClose', [ 'order_id' => $order_id ]);
  423. model('order')->commit();
  424. //订单关闭消息
  425. $message_model = new Message();
  426. $message_model->sendMessage([ 'keywords' => "ORDER_CLOSE", 'order_id' => $order_id ]);
  427. return $this->success();
  428. } catch (\Exception $e) {
  429. model('order')->rollback();
  430. return $this->error('', $e->getMessage());
  431. }
  432. }
  433. /**
  434. * 订单线上支付
  435. * @param unknown $out_trade_no
  436. */
  437. public function orderOnlinePay($data)
  438. {
  439. model('order')->startTrans();
  440. try {
  441. $out_trade_no = $data["out_trade_no"];
  442. $order_list = model("order")->getList([ [ 'out_trade_no', '=', $out_trade_no ] ], '*');
  443. $message_list = [];
  444. //订单支付消息
  445. $order_message = new OrderMessage();
  446. foreach ($order_list as $k => $order) {
  447. if ($order['order_status'] == -1) {
  448. continue;
  449. }
  450. switch ($order['order_type']) {
  451. case 1:
  452. $order_model = new Order();
  453. break;
  454. case 2:
  455. $order_model = new StoreOrder();
  456. break;
  457. case 3:
  458. $order_model = new LocalOrder();
  459. break;
  460. case 4:
  461. $order_model = new VirtualOrder();
  462. break;
  463. }
  464. $order_model->orderPay($order, $data["pay_type"]);
  465. //同时将用户表的order_money和order_num更新
  466. model('member')->setInc([ [ 'member_id', '=', $order['member_id'] ] ], 'order_money', $order['order_money']);
  467. model('member')->setInc([ [ 'member_id', '=', $order['member_id'] ] ], 'order_num');
  468. $order_message->sendMessagePay($order);
  469. //支付后商品增加销量
  470. $order_goods_list = model("order_goods")->getList([ [ "order_id", "=", $order["order_id"] ] ], "sku_id,num");
  471. $goods_model = new Goods();
  472. foreach ($order_goods_list as $ck => $v) {
  473. $goods_model->incGoodsSaleNum($v["sku_id"], $v["num"]);
  474. }
  475. //订单项增加可退款操作
  476. $order_refund_model = new OrderRefund();
  477. $order_refund_model->initOrderGoodsRefundAction([ [ "order_id", "=", $order["order_id"] ] ]);
  478. // 发送消息
  479. $message_list[] = $order;
  480. event("OrderPay", $order);
  481. }
  482. model('order')->commit();
  483. return $this->success();
  484. } catch (\Exception $e) {
  485. model('order')->rollback();
  486. return $this->error('', $e->getMessage());
  487. }
  488. }
  489. /**
  490. * 订单线下支付
  491. * @param unknown $order_id
  492. * @return unknown
  493. */
  494. public function orderOfflinePay($order_id)
  495. {
  496. model('order')->startTrans();
  497. try {
  498. $split_result = $this->splitOrderPay($order_id);
  499. if($split_result < 0)
  500. return $split_result;
  501. $out_trade_no = $split_result["data"];
  502. $pay_model = new Pay();
  503. $result = $pay_model->onlinePay($out_trade_no, "OFFLINE_PAY", '', '');
  504. if($result["code"] < 0){
  505. model('order')->rollback();
  506. return $result;
  507. }
  508. model('order')->commit();
  509. return $result;
  510. } catch (\Exception $e) {
  511. model('order')->rollback();
  512. return $this->error('', $e->getMessage());
  513. }
  514. }
  515. /**
  516. * 拆分订单
  517. * @param $order_ids
  518. * @return \multitype
  519. */
  520. public function splitOrderPay($order_ids)
  521. {
  522. $order_ids = empty($order_ids) ? [] : explode(",", $order_ids);
  523. $order_list = model("order")->getList([ [ "order_id", "in", $order_ids ], [ "pay_status", "=", 0 ] ], "pay_money,order_name,out_trade_no,order_id,pay_status");
  524. $order_count = count($order_list);
  525. //判断订单数是否匹配
  526. if (count($order_ids) > $order_count)
  527. return $this->error([], "选中订单中包含已支付数据!");
  528. $rewrite_order_ids = [];//受影响的id组
  529. $close_out_trade_no_array = [];
  530. $pay_money = 0;
  531. $pay_model = new Pay();
  532. $order_name_array = [];
  533. foreach ($order_list as $order_k => $item) {
  534. $pay_money += $item["pay_money"];//累加金额
  535. $order_name_array[] = $item["order_name"];
  536. if (!in_array($item["out_trade_no"], $close_out_trade_no_array)) {
  537. $close_out_trade_no_array[] = $item["out_trade_no"];
  538. }
  539. // $field_list = model("order")->getColumn([["out_trade_no", "=", $item["out_trade_no"]]], "order_id");
  540. }
  541. //现有的支付单据完全匹配
  542. if (count($close_out_trade_no_array) == 1) {
  543. $out_trade_no = $close_out_trade_no_array[0];
  544. //必须是有效的支付单据
  545. $pay_info_result = $pay_model->getPayInfo($out_trade_no);
  546. if (!empty($pay_info_result["data"])) {
  547. $temp_order_count = model("order")->getCount([ [ "out_trade_no", "=", $out_trade_no ], [ "order_id", "not in", $order_ids ] ], "order_id");
  548. if ($temp_order_count == 0) {
  549. return $this->success($out_trade_no);
  550. }
  551. }
  552. }
  553. //循环管理订单支付单据
  554. foreach ($close_out_trade_no_array as $close_k => $close_v) {
  555. $result = $pay_model->deletePay($close_v);//关闭旧支付单据
  556. if ($result["code"] < 0) {
  557. return $this->error([], "选中订单中包含已支付数据!");
  558. }
  559. }
  560. $order_name = implode(",", $order_name_array);
  561. //生成新的支付单据
  562. $out_trade_no = $pay_model->createOutTradeNo();
  563. $result = $pay_model->addPay(0, $out_trade_no, "", $order_name, $order_name, $pay_money, '', 'OrderPayNotify', '');
  564. //修改交易流水号为新生成的
  565. model("order")->update([ "out_trade_no" => $out_trade_no ], [ [ "order_id", "in", $order_ids ], [ "pay_status", "=", 0 ] ]);
  566. return $this->success($out_trade_no);
  567. }
  568. /**
  569. * 订单金额调整
  570. * @param string $order_product_adjust_list order_product_id:adjust_money,order_product_id:adjust_money
  571. * @param string $shipping_money
  572. */
  573. public function orderAdjustMoney($order_id, $adjust_money, $delivery_money)
  574. {
  575. model('order')->startTrans();
  576. try {
  577. //查询订单
  578. $order_info = model('order')->getInfo([ 'order_id' => $order_id ], 'out_trade_no,delivery_money, adjust_money, pay_money, order_money');
  579. if (empty($order_info))
  580. return $this->error("", "找不到订单");
  581. if ($delivery_money < 0)
  582. return $this->error("", "配送费用不能小于0!");
  583. $pay_money = $order_info["pay_money"] - $order_info["delivery_money"];//减去原来的配送费用
  584. $pay_money = $pay_money - $order_info["adjust_money"];//减去原来的调整费用
  585. $pay_money = $pay_money + $delivery_money;//加配送费用
  586. $pay_money = $pay_money + $adjust_money;
  587. if ($pay_money < 0)
  588. return $this->error("", "实际支付不能小于0!");
  589. $order_money = $order_info["order_money"] - $order_info["delivery_money"] + $delivery_money + $order_info["adjust_money"] + $adjust_money;
  590. if ($order_money < 0)
  591. return $this->error("", "订单金额不能小于0!");
  592. //关闭原支付 生成新支付
  593. $pay_model = new Pay();
  594. $pay_result = $pay_model->deletePay($order_info["out_trade_no"]);//关闭旧支付单据
  595. if ($pay_result["code"] < 0) {
  596. model('order')->rollback();
  597. return $pay_result;
  598. }
  599. $out_trade_no = $pay_result["data"];
  600. $data_order = array(
  601. 'delivery_money' => $delivery_money,
  602. 'pay_money' => $pay_money,
  603. 'adjust_money' => $adjust_money,
  604. 'order_money' => $order_money
  605. );
  606. model('order')->update($data_order, [ [ 'order_id', "=", $order_id ] ]);
  607. model('order')->commit();
  608. return $this->success();
  609. } catch (\Exception $e) {
  610. model('order')->rollback();
  611. return $this->error('', $e->getMessage());
  612. }
  613. }
  614. /**
  615. * 订单编辑
  616. * @param $data
  617. * @param $condition
  618. */
  619. public function orderUpdate($data, $condition)
  620. {
  621. $order_model = model("order");
  622. $res = $order_model->update($data, $condition);
  623. if ($res === false) {
  624. return $this->error();
  625. } else {
  626. return $this->success($res);
  627. }
  628. }
  629. /**
  630. * 订单发货
  631. * @param $order_id
  632. * @return array
  633. */
  634. public function orderCommonDelivery($order_id)
  635. {
  636. $order_common_model = new OrderCommon();
  637. $locak_result = $order_common_model->verifyOrderLock($order_id);
  638. if ($locak_result["code"] < 0)
  639. return $locak_result;
  640. $order_info = model("order")->getInfo([ [ "order_id", "=", $order_id ] ], "order_type");
  641. switch ($order_info['order_type']) {
  642. case 1:
  643. $order_model = new Order();
  644. break;
  645. case 2:
  646. $order_model = new StoreOrder();
  647. break;
  648. case 3:
  649. $order_model = new LocalOrder();
  650. break;
  651. case 4:
  652. $order_model = new VirtualOrder();
  653. break;
  654. }
  655. $result = $order_model->orderDelivery($order_id);
  656. if ($result["code"] < 0) {
  657. return $result;
  658. }
  659. //获取订单自动收货时间
  660. $config_model = new Config();
  661. $event_time_config_result = $config_model->getOrderEventTimeConfig();
  662. $event_time_config = $event_time_config_result["data"];
  663. $now_time = time();//当前时间
  664. if (!empty($event_time_config)) {
  665. $execute_time = $now_time + $event_time_config["value"]["auto_take_delivery"] * 86400;//自动收货时间
  666. } else {
  667. $execute_time = $now_time + 86400;//尚未配置 默认一天
  668. }
  669. //默认自动时间
  670. $cron_model = new Cron();
  671. $cron_model->addCron(1, 1, "订单自动收货", "CronOrderTakeDelivery", $execute_time, $order_id);
  672. event('OrderDelivery', [ 'order_id' => $order_id ]);
  673. return $result;
  674. }
  675. /**
  676. * 订单收货
  677. *
  678. * @param int $order_id
  679. */
  680. public function orderCommonTakeDelivery($order_id)
  681. {
  682. $order_info = model('order')->getInfo([ 'order_id' => $order_id ], 'order_type');
  683. if (empty($order_info))
  684. return $this->error([], "ORDER_EMPTY");
  685. $locak_result = $this->verifyOrderLock($order_id);
  686. if ($locak_result["code"] < 0)
  687. return $locak_result;
  688. switch ($order_info['order_type']) {
  689. case 1:
  690. $order_model = new Order();
  691. break;
  692. case 2:
  693. $order_model = new StoreOrder();
  694. break;
  695. case 3:
  696. $order_model = new LocalOrder();
  697. break;
  698. case 4:
  699. $order_model = new VirtualOrder();
  700. break;
  701. }
  702. model('order')->startTrans();
  703. try {
  704. $res = $order_model->orderTakeDelivery($order_id);
  705. //改变订单状态
  706. $order_data = array(
  707. 'order_status' => $order_model::ORDER_TAKE_DELIVERY,
  708. 'order_status_name' => $order_model->order_status[ $order_model::ORDER_TAKE_DELIVERY ]["name"],
  709. 'order_status_action' => json_encode($order_model->order_status[ $order_model::ORDER_TAKE_DELIVERY ], JSON_UNESCAPED_UNICODE),
  710. "is_evaluate" => 1,
  711. "evaluate_status" => 0,
  712. "evaluate_status_name" => "待评价",
  713. "sign_time" => time()
  714. );
  715. $res = model('order')->update($order_data, [ [ 'order_id', '=', $order_id ] ]);
  716. $this->addCronOrderComplete($order_id);
  717. event('OrderTakeDelivery', [ 'order_id' => $order_id ]);
  718. model('order')->commit();
  719. //订单收货消息
  720. $message_model = new Message();
  721. $message_model->sendMessage([ 'keywords' => "ORDER_TAKE_DELIVERY", 'order_id' => $order_id ]);
  722. return $this->success();
  723. } catch (\Exception $e) {
  724. model('order')->rollback();
  725. return $this->error('', $e->getMessage());
  726. }
  727. }
  728. /**
  729. * 添加订单自动完成事件
  730. * @param $order_id
  731. */
  732. public function addCronOrderComplete($order_id)
  733. {
  734. //获取订单自动完成时间
  735. $config_model = new Config();
  736. $event_time_config_result = $config_model->getOrderEventTimeConfig();
  737. $event_time_config = $event_time_config_result["data"];
  738. $now_time = time();
  739. if (!empty($event_time_config)) {
  740. $execute_time = $now_time + $event_time_config["value"]["auto_complete"] * 86400;//自动完成时间
  741. } else {
  742. $execute_time = $now_time + 86400;//尚未配置 默认一天
  743. }
  744. //设置订单自动完成事件
  745. $cron_model = new Cron();
  746. $result = $cron_model->addCron(1, 0, "订单自动完成", "CronOrderComplete", $execute_time, $order_id);
  747. return $this->success($result);
  748. }
  749. /**
  750. * 订单解除锁定
  751. * @param $order_id
  752. */
  753. public function orderUnlock($order_id)
  754. {
  755. $data = array(
  756. "is_lock" => 0
  757. );
  758. $res = model("order")->update($data, [ [ "order_id", "=", $order_id ] ]);
  759. return $res;
  760. }
  761. /**
  762. * 订单锁定
  763. * @param $order_id
  764. * @return mixed
  765. */
  766. public function orderLock($order_id)
  767. {
  768. $data = array(
  769. "is_lock" => 1
  770. );
  771. $res = model("order")->update($data, [ [ "order_id", "=", $order_id ] ]);
  772. return $res;
  773. }
  774. /**
  775. * 验证订单锁定状态
  776. * @param $order_id
  777. */
  778. public function verifyOrderLock($param)
  779. {
  780. if (!is_array($param)) {
  781. $order_info = model("order")->getInfo([ [ "order_id", "=", $param ] ], "is_lock");
  782. } else {
  783. $order_info = $param;
  784. }
  785. if ($order_info["is_lock"] == 1) {//判断订单锁定状态
  786. model('order')->rollback();
  787. return $this->error('', "ORDER_LOCK");
  788. } else {
  789. $this->success();
  790. }
  791. }
  792. /**********************************************************************************订单操作基础方法(订单关闭,订单完成,订单调价)结束********/
  793. /****************************************************************************订单数据查询(开始)*************************************/
  794. /**
  795. * 获取订单详情
  796. *
  797. * @param array $order_id
  798. */
  799. public function getOrderDetail($order_id)
  800. {
  801. $order_info = model('order')->getInfo([ [ 'order_id', "=", $order_id ] ]);
  802. if (empty($order_info))
  803. return $this->error('');
  804. $member_info = model('member')->getInfo([ [ 'member_id', "=", $order_info['member_id'] ] ], 'nickname');
  805. $order_info['nickname'] = $member_info['nickname'];
  806. $order_goods_list = model('order_goods')->getList([ [ 'order_id', "=", $order_id ] ]);
  807. $order_info['order_goods'] = $order_goods_list;
  808. //包裹化数据
  809. $express_package_model = new ExpressPackage();
  810. $package_list = $express_package_model->package([ [ "order_id", "=", $order_id ] ]);
  811. $order_info["package_list"] = $package_list;
  812. return $this->success($order_info);
  813. }
  814. /**
  815. * 得到订单基础信息
  816. * @param $condition
  817. * @param string $field
  818. */
  819. public function getOrderInfo($condition, $field = "*")
  820. {
  821. $res = model("order")->getInfo($condition, $field);
  822. return $this->success($res);
  823. }
  824. /**
  825. * 得到订单数量
  826. * @param $condition
  827. * @param string $field
  828. */
  829. public function getOrderCount($condition)
  830. {
  831. $res = model("order")->getCount($condition);
  832. return $this->success($res);
  833. }
  834. /**
  835. * 获取订单列表
  836. *
  837. * @param array $condition
  838. * @param string $field
  839. * @param string $order
  840. * @param string $limit
  841. */
  842. public function getOrderList($condition = [], $field = '*', $order = '', $limit = null)
  843. {
  844. $list = model('order')->getList($condition, $field, $order, '', '', '', $limit);
  845. return $this->success($list);
  846. }
  847. /**
  848. * 获取订单分页列表
  849. *
  850. * @param array $condition
  851. * @param number $page
  852. * @param string $page_size
  853. * @param string $order
  854. * @param string $field
  855. */
  856. public function getOrderPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
  857. {
  858. $order_list = model('order')->pageList($condition, $field, $order, $page, $page_size);
  859. if (!empty($order_list['list'])) {
  860. foreach ($order_list['list'] as $k => $v) {
  861. $order_goods_list = model("order_goods")->getList([
  862. 'order_id' => $v['order_id']
  863. ]);
  864. $order_list['list'][ $k ]['order_goods'] = $order_goods_list;
  865. }
  866. }
  867. return $this->success($order_list);
  868. }
  869. /**
  870. * 订单列表(已商品为主)
  871. * @param array $condition
  872. * @return array
  873. */
  874. public function getOrderGoodsDetailList($condition = [])
  875. {
  876. $alias = 'og';
  877. $join = [
  878. [
  879. 'order o',
  880. 'o.order_id = og.order_id',
  881. 'left'
  882. ]
  883. ];
  884. $order_field = 'o.order_no,o.site_name,o.order_name,o.order_from_name,o.order_type_name,o.order_promotion_name,o.out_trade_no,o.out_trade_no_2,o.delivery_code,o.order_status_name,o.pay_status,o.delivery_status,o.refund_status,o.pay_type_name,o.delivery_type_name,o.name,o.mobile,o.telephone,o.full_address,o.buyer_ip,o.buyer_ask_delivery_time,o.buyer_message,o.goods_money,o.delivery_money,o.promotion_money,o.coupon_money,o.order_money,o.adjust_money,o.balance_money,o.pay_money,o.refund_money,o.pay_time,o.delivery_time,o.sign_time,o.finish_time,o.remark,o.goods_num,o.delivery_status_name,o.shop_money,o.platform_money,o.is_settlement,o.delivery_store_name,o.promotion_type_name,';
  885. $order_goods_field = 'og.sku_name,og.sku_no,og.is_virtual,og.goods_class_name,og.price,og.cost_price,og.num,og.goods_money,og.cost_money,og.delivery_no,og.refund_no,og.refund_type,og.refund_apply_money,og.refund_reason,og.refund_real_money,og.refund_delivery_name,og.refund_delivery_no,og.refund_time,og.refund_refuse_reason,og.refund_action_time,og.commission_rate,og.real_goods_money,og.shop_money,og.platform_money,og.refund_remark,og.refund_delivery_remark,og.refund_address,og.is_refund_stock';
  886. $list = model('order_goods')->getList($condition, $order_field . $order_goods_field, 'og.order_goods_id desc', $alias, $join);
  887. return $this->success($list);
  888. }
  889. /**
  890. * 获取订单项详情
  891. * @param array $condition
  892. * @param string $field
  893. * @return array
  894. */
  895. public function getOrderGoodsInfo($condition = [], $field = '*')
  896. {
  897. $info = model("order_goods")->getInfo($condition, $field);
  898. return $this->success($info);
  899. }
  900. /**
  901. * 获取订单列表
  902. * @param array $condition
  903. * @param string $field
  904. * @param string $order
  905. * @param string $limit
  906. */
  907. public function getOrderGoodsList($condition = [], $field = '*', $order = '', $limit = null, $group = '')
  908. {
  909. $list = model('order_goods')->getList($condition, $field, $order, '', '', $group, $limit);
  910. return $this->success($list);
  911. }
  912. /****************************************************************************订单数据查询结束*************************************/
  913. /****************************************************************************会员订单订单数据查询开始*************************************/
  914. /**
  915. * 会员订单详情
  916. * @param $order_id
  917. * @param $member_id
  918. */
  919. public function getMemberOrderDetail($order_id, $member_id)
  920. {
  921. $order_info = model('order')->getInfo([ [ 'order_id', "=", $order_id ], [ "member_id", "=", $member_id ] ]);
  922. if (empty($order_info))
  923. return $this->error([], "当前订单不是本账号的订单!");
  924. $action = empty($order_info["order_status_action"]) ? [] : json_decode($order_info["order_status_action"], true);
  925. $member_action = $action["member_action"] ?? [];
  926. $order_info['action'] = $member_action;
  927. $order_goods_list = model('order_goods')->getList([ [ 'order_id', "=", $order_id ], [ "member_id", "=", $member_id ] ]);
  928. $complain_model = new Complain();
  929. foreach ($order_goods_list as $k => $v) {
  930. $refund_action = empty($v["refund_status_action"]) ? [] : json_decode($v["refund_status_action"], true);
  931. $refund_action = $refund_action["member_action"] ?? [];
  932. $order_goods_list[ $k ]["refund_action"] = $refund_action;
  933. //判断维权操作
  934. $complain_action = 0;
  935. //订单项未退款完毕 订单未完成 为关闭
  936. if ($v["refund_status"] != 3 && $v["refund_status"] != 0 && !in_array($order_info["order_status"], [ -1, 10 ])) {
  937. // $complain_info_result = $complain_model->getComplainInfo([["order_goods_id", "=", $v["order_goods_id"]]]);
  938. // $complain_info = $complain_info_result["data"];
  939. // if(!empty($complain_info)){
  940. // $complain_action = empty($v["complain_status_action"]) ? [] : json_decode($v["complain_status_action"], true);
  941. // $complain_action = $complain_action["member_action"] ?? [];
  942. // }else{
  943. // $complain_action = [
  944. // 'event' => 'complain',
  945. // 'title' => '平台维权',
  946. // 'color' => ''
  947. // ];
  948. // }
  949. $complain_action = 1;
  950. }
  951. $order_goods_list[ $k ]["complain_action"] = $complain_action;
  952. }
  953. $order_info['order_goods'] = $order_goods_list;
  954. $code_result = $this->orderQrcode($order_info);
  955. $order_info = array_merge($order_info, $code_result);
  956. $order_info["code_info"] = $code_result;
  957. switch ($order_info['order_type']) {
  958. case 1:
  959. $order_model = new Order();
  960. break;
  961. case 2:
  962. $order_model = new StoreOrder();
  963. break;
  964. case 3:
  965. $order_model = new LocalOrder();
  966. break;
  967. case 4:
  968. $order_model = new VirtualOrder();
  969. break;
  970. }
  971. $temp_info = $order_model->orderDetail($order_info);
  972. $order_info = array_merge($order_info, $temp_info);
  973. return $this->success($order_info);
  974. }
  975. /**
  976. * 会员订单分页列表
  977. * @param array $condition
  978. * @param int $page
  979. * @param int $page_size
  980. * @param string $order
  981. * @param string $field
  982. * @return \multitype
  983. */
  984. public function getMemberOrderPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
  985. {
  986. $order_list = model('order')->pageList($condition, $field, $order, $page, $page_size);
  987. if (!empty($order_list['list'])) {
  988. foreach ($order_list['list'] as $k => $v) {
  989. $order_goods_list = model("order_goods")->getList([
  990. 'order_id' => $v['order_id']
  991. ]);
  992. $order_list['list'][ $k ]['order_goods'] = $order_goods_list;
  993. $action = empty($v["order_status_action"]) ? [] : json_decode($v["order_status_action"], true);
  994. $member_action = $action["member_action"] ?? [];
  995. $order_list['list'][ $k ]['action'] = $member_action;
  996. }
  997. }
  998. return $this->success($order_list);
  999. }
  1000. /**
  1001. * 订单生成码
  1002. * @param $order_info
  1003. * @param $is_create
  1004. */
  1005. public function orderQrcode($order_info)
  1006. {
  1007. $app_type = input("app_type");
  1008. switch ($order_info['order_type']) {
  1009. case 2:
  1010. $code = $order_info["delivery_code"];
  1011. $verify_type = "pickup";
  1012. break;
  1013. case 4:
  1014. $code = $order_info["virtual_code"];
  1015. $verify_type = "virtualgoods";
  1016. break;
  1017. default:
  1018. return [];
  1019. }
  1020. $verify_model = new Verify();
  1021. $result = $verify_model->qrcode($code, $app_type, $verify_type, "get");
  1022. $data = [];
  1023. if (!empty($result) && $result["code"] >= 0) {
  1024. $data[ $verify_type ] = $result["data"]["path"];
  1025. }
  1026. return $data;
  1027. }
  1028. /****************************************************************************会员订单订单数据查询结束*************************************/
  1029. /***************************************************************** 交易记录 *****************************************************************/
  1030. /**
  1031. * 获取交易记录分页列表
  1032. *
  1033. * @param array $condition
  1034. * @param number $page
  1035. * @param string $page_size
  1036. * @param string $order
  1037. * @param string $field
  1038. */
  1039. public function getTradePageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
  1040. {
  1041. $list = model('order')->pageList($condition, $field, $order, $page, $page_size);
  1042. return $this->success($list);
  1043. }
  1044. /***************************************************************** 交易记录 *****************************************************************/
  1045. }