VirtualOrder.php 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace app\model\order;
  11. use addon\cardservice\model\MemberCard;
  12. use app\model\goods\VirtualGoods;
  13. use app\model\system\Cron;
  14. use app\model\verify\Verify as VerifyModel;
  15. use app\model\verify\VerifyRecord;
  16. /**
  17. * 虚拟订单
  18. *
  19. * @author Administrator
  20. *
  21. */
  22. class VirtualOrder extends OrderCommon
  23. {
  24. /*****************************************************************************************订单状态***********************************************/
  25. // 订单创建
  26. const ORDER_CREATE = 0;
  27. // 订单已支付
  28. const ORDER_PAY = 1;
  29. // 订单待收货
  30. const ORDER_DELIVERY = 3;
  31. // 订单已收货
  32. const ORDER_TAKE_DELIVERY = 4;
  33. // 订单已结算完成
  34. const ORDER_COMPLETE = 10;
  35. // 订单已关闭
  36. const ORDER_CLOSE = -1;
  37. // 订单待使用
  38. const ORDER_WAIT_VERIFY = 11;
  39. //订单已使用
  40. const ORDER_VERIFYED = 12;
  41. /**
  42. * 订单类型
  43. *
  44. * @var int
  45. */
  46. public $order_type = 4;
  47. public $order_status = [
  48. self::ORDER_CREATE => [
  49. 'status' => self::ORDER_CREATE,
  50. 'name' => '待支付',
  51. 'is_allow_refund' => 0,
  52. 'icon' => 'public/uniapp/order/order-icon.png',
  53. 'action' => [
  54. [
  55. 'action' => 'orderClose',
  56. 'title' => '关闭订单',
  57. 'color' => ''
  58. ],
  59. [
  60. 'action' => 'orderAdjustMoney',
  61. 'title' => '调整价格',
  62. 'color' => ''
  63. ],
  64. ],
  65. 'member_action' => [
  66. [
  67. 'action' => 'orderClose',
  68. 'title' => '关闭订单',
  69. 'color' => ''
  70. ],
  71. [
  72. 'action' => 'orderPay',
  73. 'title' => '支付',
  74. 'color' => ''
  75. ],
  76. ],
  77. 'color' => ''
  78. ],
  79. self::ORDER_PAY => [
  80. 'status' => self::ORDER_PAY,
  81. 'name' => '待发货',
  82. 'is_allow_refund' => 0,
  83. 'icon' => 'public/uniapp/order/order-icon-send.png',
  84. 'action' => [
  85. [
  86. 'action' => 'orderVirtualDelivery',
  87. 'title' => '发货',
  88. 'color' => ''
  89. ],
  90. ],
  91. 'member_action' => [],
  92. 'color' => ''
  93. ],
  94. self::ORDER_DELIVERY => [
  95. 'status' => self::ORDER_DELIVERY,
  96. 'name' => '待收货',
  97. 'is_allow_refund' => 1,
  98. 'icon' => 'public/uniapp/order/order-icon-received.png',
  99. 'action' => [
  100. ],
  101. 'member_action' => [
  102. [
  103. 'action' => 'memberVirtualTakeDelivery',
  104. 'title' => '确认使用',
  105. 'color' => ''
  106. ],
  107. ],
  108. 'color' => ''
  109. ],
  110. self::ORDER_TAKE_DELIVERY => [
  111. 'status' => self::ORDER_TAKE_DELIVERY,
  112. 'name' => '已收货',
  113. 'is_allow_refund' => 1,
  114. 'icon' => 'public/uniapp/order/order-icon-received.png',
  115. 'action' => [
  116. ],
  117. 'member_action' => [
  118. ],
  119. 'color' => ''
  120. ],
  121. self::ORDER_WAIT_VERIFY => [
  122. 'status' => self::ORDER_WAIT_VERIFY,
  123. 'name' => '待使用',
  124. 'is_allow_refund' => 1,
  125. 'icon' => 'public/uniapp/order/order-icon-close.png',
  126. 'action' => [
  127. ],
  128. 'member_action' => [
  129. ],
  130. 'color' => ''
  131. ],
  132. self::ORDER_VERIFYED => [
  133. 'status' => self::ORDER_VERIFYED,
  134. 'name' => '已使用',
  135. 'is_allow_refund' => 1,
  136. 'icon' => 'public/uniapp/order/order-icon-close.png',
  137. 'action' => [
  138. ],
  139. 'member_action' => [
  140. ],
  141. 'color' => ''
  142. ],
  143. self::ORDER_COMPLETE => [
  144. 'status' => self::ORDER_COMPLETE,
  145. 'name' => '已完成',
  146. 'is_allow_refund' => 1,
  147. 'icon' => 'public/uniapp/order/order-icon-received.png',
  148. 'action' => [
  149. ],
  150. 'member_action' => [
  151. ],
  152. 'color' => ''
  153. ],
  154. self::ORDER_CLOSE => [
  155. 'status' => self::ORDER_CLOSE,
  156. 'name' => '已关闭',
  157. 'is_allow_refund' => 0,
  158. 'icon' => 'public/uniapp/order/order-icon-close.png',
  159. 'action' => [
  160. ],
  161. 'member_action' => [
  162. ],
  163. 'color' => ''
  164. ],
  165. ];
  166. /**
  167. * 订单支付
  168. * @param unknown $order_info
  169. */
  170. public function orderPay($order_info, $pay_type, $log_data = [])
  171. {
  172. $pay_type_list = $this->getPayType();
  173. $data = array (
  174. 'order_status' => self::ORDER_PAY,
  175. 'order_status_name' => $this->order_status[ self::ORDER_PAY ][ "name" ],
  176. 'order_status_action' => json_encode($this->order_status[ self::ORDER_PAY ], JSON_UNESCAPED_UNICODE),
  177. "pay_status" => 1,
  178. "pay_time" => time(),
  179. "is_enable_refund" => 1,
  180. "pay_type" => $pay_type,
  181. "pay_type_name" => $pay_type_list[ $pay_type ]
  182. );
  183. //记录订单日志 start
  184. $action = '商家对订单进行了线下支付';
  185. //获取用户信息
  186. if (empty($log_data)) {
  187. $member_info = model('member')->getInfo([ 'member_id' => $order_info[ 'member_id' ] ], 'nickname');
  188. $log_data = [
  189. 'uid' => $order_info[ 'member_id' ],
  190. 'nick_name' => $member_info[ 'nickname' ],
  191. 'action_way' => 1
  192. ];
  193. $buyer_name = empty($member_info[ 'nickname' ]) ? '' : '【' . $member_info[ 'nickname' ] . '】';
  194. $action = '买家' . $buyer_name . '支付了订单';
  195. }
  196. $log_data = array_merge($log_data, [
  197. 'order_id' => $order_info[ 'order_id' ],
  198. 'action' => $action,
  199. 'order_status' => self::ORDER_PAY,
  200. 'order_status_name' => $this->order_status[ self::ORDER_PAY ][ "name" ],
  201. ]);
  202. $this->addOrderLog($log_data);
  203. //记录订单日志 end
  204. $res = model('order')->update($data, [ [ 'order_id', "=", $order_info[ 'order_id' ] ] ]);
  205. $goods_id = model('order_goods')->getValue([ [ 'order_id', '=', $order_info[ 'order_id' ] ] ], 'goods_id');
  206. //判断商品是否需要核销
  207. $goods_info = model('goods')->getInfo([ [ 'goods_id', '=', $goods_id ] ], 'goods_class,is_need_verify,virtual_deliver_type');
  208. if ($order_info[ 'is_lock' ] == 0) {
  209. if (in_array($order_info[ 'promotion_type' ], [ 'pintuan', 'pinfan' ])) {
  210. } else {
  211. if ($goods_info[ 'goods_class' ] == 2) {
  212. switch ( $goods_info[ 'virtual_deliver_type' ] ) {
  213. case 'auto_deliver'://自动发货
  214. $result = $this->virtualDelivery($order_info);//
  215. break;
  216. case 'artificial_deliver'://手动发货
  217. break;
  218. case 'verify'://到店核销
  219. //核销次数 is_need_verify
  220. $order_status_item = $this->order_status[ self::ORDER_WAIT_VERIFY ];
  221. // $order_status_item['name'] = '待使用';
  222. // $order_status_item['action'] = [];
  223. // $order_status_item['member_action'] = [];
  224. $data = array (
  225. 'order_status' => self::ORDER_WAIT_VERIFY,
  226. 'order_status_name' => $order_status_item[ 'name' ],
  227. 'order_status_action' => json_encode($order_status_item, JSON_UNESCAPED_UNICODE),
  228. );
  229. $res = model('order')->update($data, [ [ 'order_id', "=", $order_info[ 'order_id' ] ] ]);
  230. if ($goods_info[ 'is_need_verify' ]) {
  231. //虚拟产品发货
  232. $this->virtualOrderTakeDelivery($order_info[ 'order_id' ]);
  233. } else {
  234. //虚拟产品收货
  235. $this->orderCommonTakeDelivery($order_info[ 'order_id' ]);
  236. }
  237. break;
  238. }
  239. } elseif ($goods_info[ 'goods_class' ] == 3) {
  240. $order_status_item = $this->order_status[ self::ORDER_DELIVERY ];
  241. $order_status_item[ 'action' ] = [];
  242. $order_status_item[ 'member_action' ] = [];
  243. $data = array (
  244. 'order_status' => self::ORDER_DELIVERY,
  245. 'order_status_name' => $this->order_status[ self::ORDER_DELIVERY ][ "name" ],
  246. 'order_status_action' => json_encode($order_status_item, JSON_UNESCAPED_UNICODE),
  247. );
  248. $res = model('order')->update($data, [ [ 'order_id', "=", $order_info[ 'order_id' ] ] ]);
  249. // 卡密商品发货
  250. $result = $this->virtualcardTakeDelivery($order_info[ 'order_id' ]);
  251. if ($result[ 'code' ] < 0) {
  252. return $result;
  253. }
  254. } elseif ($goods_info[ 'goods_class' ] == 4) {
  255. $order_status_item = $this->order_status[ self::ORDER_DELIVERY ];
  256. $order_status_item[ 'action' ] = [];
  257. $order_status_item[ 'member_action' ] = [];
  258. $data = array (
  259. 'order_status' => self::ORDER_DELIVERY,
  260. 'order_status_name' => $this->order_status[ self::ORDER_DELIVERY ][ "name" ],
  261. 'order_status_action' => json_encode($order_status_item, JSON_UNESCAPED_UNICODE),
  262. );
  263. $res = model('order')->update($data, [ [ 'order_id', "=", $order_info[ 'order_id' ] ] ]);
  264. $this->serviceGoodsTakeDelivery($order_info[ 'order_id' ]);
  265. } elseif ($goods_info[ 'goods_class' ] == 5) {
  266. $order_status_item = $this->order_status[ self::ORDER_DELIVERY ];
  267. $order_status_item[ 'action' ] = [];
  268. $order_status_item[ 'member_action' ] = [];
  269. $data = array (
  270. 'order_status' => self::ORDER_DELIVERY,
  271. 'order_status_name' => $this->order_status[ self::ORDER_DELIVERY ][ "name" ],
  272. 'order_status_action' => json_encode($order_status_item, JSON_UNESCAPED_UNICODE),
  273. );
  274. $res = model('order')->update($data, [ [ 'order_id', "=", $order_info[ 'order_id' ] ] ]);
  275. $this->cardServiceTakeDelivery($order_info[ 'order_id' ]);
  276. }
  277. }
  278. }
  279. return $this->success($res);
  280. }
  281. /**
  282. * 订单自动发货
  283. * @param unknown $order_id
  284. */
  285. public function virtualOrderTakeDelivery($order_id)
  286. {
  287. $order_info = model('order')->getInfo([ [ 'order_id', '=', $order_id ] ], 'order_no,site_id,site_name,member_id,order_type,
  288. sign_time,order_status,delivery_code,create_time,name,pay_time,pay_money,mobile,is_lock,order_money');
  289. if (empty($order_info))
  290. return $this->error([], "ORDER_EMPTY");
  291. model('order')->startTrans();
  292. try {
  293. //订单项变为已发货
  294. model('order_goods')->update([ 'delivery_status' => 1, 'delivery_status_name' => '待使用' ], [ [ 'order_id', '=', $order_id ] ]);
  295. $order_goods_info = model('order_goods')->getInfo([ [ 'order_id', '=', $order_id ] ], 'sku_id,sku_name,sku_image,price,num,goods_id,order_goods_id');//订单项详情
  296. if (!empty($order_goods_info)) {
  297. $order_goods_info[ 'num' ] = numberFormat($order_goods_info[ 'num' ]);
  298. }
  299. //判断商品是否需要核销
  300. $goods_info = model('goods_sku')->getInfo([ [ 'gs.sku_id', '=', $order_goods_info[ 'sku_id' ] ] ], 'g.is_need_verify,g.verify_validity_type,g.virtual_indate,gs.verify_num', 'gs', [ [ 'goods g', 'g.goods_id = gs.goods_id', 'left' ] ]);
  301. if ($goods_info[ 'is_need_verify' ]) {
  302. switch ( $goods_info[ 'verify_validity_type' ] ) {
  303. case 0:
  304. $expire_time = 0;
  305. break;
  306. case 1:
  307. $expire_time = strtotime('+' . $goods_info[ 'virtual_indate' ] . 'days');
  308. break;
  309. case 2:
  310. $expire_time = $goods_info[ 'virtual_indate' ];
  311. break;
  312. }
  313. // dump($expire_time);
  314. //添加自动收货事件
  315. if ($expire_time > 0) {
  316. $cron = new Cron();
  317. $cron->addCron(1, 0, "订单自动收货", "CronOrderTakeDelivery", $expire_time, $order_id);
  318. // 核销码临近到期时间(小时)
  319. $config_model = new Config();
  320. $verify_config = $config_model->getOrderVerifyConfig($order_info[ 'site_id' ], 'shop')[ 'data' ][ 'value' ];
  321. $order_verify_out_time = $verify_config[ 'order_verify_time_out' ] ?? 24;
  322. $time_strtime = $order_verify_out_time * 3600;
  323. //核销商品临期提醒
  324. $cron->addCron(1, 0, "核销商品临期提醒", "VerifyOrderOutTime", $expire_time - $time_strtime, $order_id);
  325. //核销码过期提醒
  326. $cron->addCron(1, 0, "核销码过期提醒", "CronVerifyCodeExpire", $expire_time, $order_id);
  327. }
  328. $count = $goods_info[ 'verify_num' ] * $order_goods_info[ 'num' ];
  329. // for ($i = 1; $i <= $count; $i++) {
  330. //创建待核销记录
  331. $verify_model = new VerifyModel();
  332. $item_array = array (
  333. [
  334. "img" => $order_goods_info[ "sku_image" ],
  335. "name" => $order_goods_info[ "sku_name" ],
  336. "price" => $order_goods_info[ "price" ],
  337. "num" => 1,
  338. "order_goods_id" => $order_goods_info[ "order_goods_id" ],
  339. "remark_array" => [
  340. [ "title" => "联系人", "value" => $order_info[ 'name' ] . $order_info[ 'mobile' ] ]
  341. ]
  342. ],
  343. );
  344. $remark_array = array (
  345. [ "title" => '订单金额', "value" => $order_info[ "order_money" ] ],
  346. [ "title" => '订单编号', "value" => $order_info[ "order_no" ] ],
  347. [ "title" => '创建时间', "value" => time_to_date($order_info[ "create_time" ]) ],
  348. [ "title" => '付款时间', "value" => time_to_date($order_info[ "pay_time" ]) ],
  349. );
  350. $verify_content_json = $verify_model->getVerifyJson($item_array, $remark_array);
  351. $code_result = $verify_model->addVerify("virtualgoods", $order_info[ 'site_id' ], $order_info[ 'site_name' ], $verify_content_json, $expire_time, $count, 0, $order_info[ 'member_id' ]);
  352. $code = $code_result[ "data" ][ "verify_code" ];
  353. $result = $verify_model->qrcode($code, "all", "virtualgoods", $order_info[ 'site_id' ], "create");//生成二维码
  354. //自动收发货
  355. $order_data = array (
  356. 'virtual_code' => $code,
  357. );
  358. $res = model('order')->update($order_data, [ [ 'order_id', '=', $order_id ] ]);
  359. //生成所购买的产品
  360. $virtual_goods_model = new VirtualGoods();
  361. $goods_virtual_data = [
  362. 'site_id' => $order_info[ 'site_id' ],
  363. 'order_id' => $order_id,
  364. 'order_no' => $order_info[ 'order_no' ],
  365. 'sku_id' => $order_goods_info[ 'sku_id' ],
  366. 'sku_name' => $order_goods_info[ 'sku_name' ],
  367. 'code' => $code,
  368. 'member_id' => $order_info[ 'member_id' ],
  369. 'sku_image' => $order_goods_info[ 'sku_image' ],
  370. 'expire_time' => $expire_time,
  371. 'sold_time' => time(),
  372. 'goods_id' => $order_goods_info[ 'goods_id' ],
  373. 'verify_total_count' => $count
  374. ];
  375. $virtual_goods_model->addGoodsVirtual($goods_virtual_data);
  376. // }
  377. }
  378. model('order')->commit();
  379. return $this->success($res);
  380. } catch (\Exception $e) {
  381. model('order')->rollback();
  382. return $this->error('', $e->getMessage());
  383. }
  384. }
  385. /**
  386. * 订单自动发货
  387. * @param unknown $order_id
  388. */
  389. public function serviceGoodsTakeDelivery($order_id)
  390. {
  391. $order_info = model('order')->getInfo([ [ 'order_id', '=', $order_id ] ], 'order_no,site_id,site_name,member_id,order_type,
  392. sign_time,order_status,delivery_code,create_time,name,pay_time,pay_money,mobile,is_lock,order_money');
  393. if (empty($order_info))
  394. return $this->error([], "ORDER_EMPTY");
  395. model('order')->startTrans();
  396. try {
  397. //订单项变为已发货
  398. model('order_goods')->update([ 'delivery_status' => 1, "delivery_status_name" => "已发货" ], [ [ 'order_id', "=", $order_id ] ]);
  399. $order_goods_info = model('order_goods')->getInfo([ [ 'order_id', '=', $order_id ] ], 'sku_id,sku_name,sku_image,price,num,goods_id,order_goods_id');//订单项详情
  400. if (!empty($order_goods_info)) {
  401. $order_goods_info[ 'num' ] = numberFormat($order_goods_info[ 'num' ]);
  402. }
  403. //判断商品是否需要核销
  404. $goods_info = model('goods_sku')->getInfo([ [ 'gs.sku_id', '=', $order_goods_info[ 'sku_id' ] ] ], 'g.is_need_verify,g.verify_validity_type,g.virtual_indate,gs.verify_num', 'gs', [ [ 'goods g', 'g.goods_id = gs.goods_id', 'left' ] ]);
  405. switch ( $goods_info[ 'verify_validity_type' ] ) {
  406. case 0:
  407. $expire_time = 0;
  408. break;
  409. case 1:
  410. $expire_time = strtotime('+' . $goods_info[ 'virtual_indate' ] . 'days');
  411. break;
  412. case 2:
  413. $expire_time = $goods_info[ 'virtual_indate' ];
  414. break;
  415. }
  416. // dump($expire_time);
  417. //添加自动收货事件
  418. if ($expire_time > 0) {
  419. $cron = new Cron();
  420. $cron->addCron(1, 0, "订单自动收货", "CronOrderTakeDelivery", $expire_time, $order_id);
  421. // 核销码临近到期时间(小时)
  422. $config_model = new Config();
  423. $verify_config = $config_model->getOrderVerifyConfig($order_info[ 'site_id' ], 'shop')[ 'data' ][ 'value' ];
  424. $order_verify_out_time = $verify_config[ 'order_verify_time_out' ] ?? 24;
  425. $time_strtime = $order_verify_out_time * 3600;
  426. //核销商品临期提醒
  427. $cron->addCron(1, 0, "核销商品临期提醒", "VerifyOrderOutTime", $expire_time - $time_strtime, $order_id);
  428. //核销码过期提醒
  429. $cron->addCron(1, 0, "核销码过期提醒", "CronVerifyCodeExpire", $expire_time, $order_id);
  430. }
  431. $count = $order_goods_info[ 'num' ];
  432. //创建待核销记录
  433. $verify_model = new VerifyModel();
  434. $item_array = array (
  435. [
  436. "img" => $order_goods_info[ "sku_image" ],
  437. "name" => $order_goods_info[ "sku_name" ],
  438. "price" => $order_goods_info[ "price" ],
  439. "num" => 1,
  440. "order_goods_id" => $order_goods_info[ "order_goods_id" ],
  441. "remark_array" => [
  442. [ "title" => "联系人", "value" => $order_info[ 'name' ] . $order_info[ 'mobile' ] ]
  443. ]
  444. ],
  445. );
  446. $remark_array = array (
  447. [ "title" => '订单金额', "value" => $order_info[ "order_money" ] ],
  448. [ "title" => '订单编号', "value" => $order_info[ "order_no" ] ],
  449. [ "title" => '创建时间', "value" => time_to_date($order_info[ "create_time" ]) ],
  450. [ "title" => '付款时间', "value" => time_to_date($order_info[ "pay_time" ]) ],
  451. );
  452. $verify_content_json = $verify_model->getVerifyJson($item_array, $remark_array);
  453. $code_result = $verify_model->addVerify("virtualgoods", $order_info[ 'site_id' ], $order_info[ 'site_name' ], $verify_content_json, $expire_time, $count, 0, $order_info[ 'member_id' ]);
  454. $code = $code_result[ "data" ][ "verify_code" ];
  455. $result = $verify_model->qrcode($code, "all", "virtualgoods", $order_info[ 'site_id' ], "create");//生成二维码
  456. //自动收发货
  457. $order_data = array (
  458. 'virtual_code' => $code,
  459. );
  460. $res = model('order')->update($order_data, [ [ 'order_id', '=', $order_id ] ]);
  461. //生成所购买的产品
  462. $virtual_goods_model = new VirtualGoods();
  463. $goods_virtual_data = [
  464. 'site_id' => $order_info[ 'site_id' ],
  465. 'order_id' => $order_id,
  466. 'order_no' => $order_info[ 'order_no' ],
  467. 'sku_id' => $order_goods_info[ 'sku_id' ],
  468. 'sku_name' => $order_goods_info[ 'sku_name' ],
  469. 'code' => $code,
  470. 'member_id' => $order_info[ 'member_id' ],
  471. 'sku_image' => $order_goods_info[ 'sku_image' ],
  472. 'expire_time' => $expire_time,
  473. 'sold_time' => time(),
  474. 'goods_id' => $order_goods_info[ 'goods_id' ],
  475. 'verify_total_count' => $count
  476. ];
  477. $virtual_goods_model->addGoodsVirtual($goods_virtual_data);
  478. model('order')->commit();
  479. return $this->success($res);
  480. } catch (\Exception $e) {
  481. model('order')->rollback();
  482. return $this->error('', $e->getMessage());
  483. }
  484. }
  485. /**
  486. * 卡密商品自动发货 收货(可以分为两个函数 一个发货一个收货)
  487. * @param $order_id
  488. */
  489. public function virtualcardTakeDelivery($order_id)
  490. {
  491. $order_info = model('order')->getInfo([ [ 'order_id', '=', $order_id ] ], 'order_no,site_id,site_name,member_id,order_type,
  492. sign_time,order_status,delivery_code,create_time,name,pay_time,pay_money,mobile,is_lock,order_money');
  493. if (empty($order_info))
  494. return $this->error([], "ORDER_EMPTY");
  495. model('order')->startTrans();
  496. try {
  497. //订单项变为已发货
  498. model('order_goods')->update([ 'delivery_status' => 1, "delivery_status_name" => "已发货" ], [ [ 'order_id', "=", $order_id ] ]);
  499. $order_goods_info = model('order_goods')->getInfo([ [ 'order_id', '=', $order_id ] ], '*');//订单项详情
  500. if (!empty($order_goods_info)) {
  501. $order_goods_info[ 'num' ] = numberFormat($order_goods_info[ 'num' ]);
  502. }
  503. //库存处理(卡密商品支付后在扣出库存)//todo 可以再商品中设置扣除库存步骤
  504. $order_stock_model = new OrderStock();
  505. $item_goods_class = $order_goods_info[ 'goods_class' ];
  506. if ($item_goods_class == 3) {
  507. //库存变化
  508. $stock_result = $order_stock_model->decOrderStock($order_goods_info);
  509. if ($stock_result[ 'code' ] < 0) {
  510. //主动退款
  511. $order_refund_model = new OrderRefund();
  512. $refund_result = $order_refund_model->activeRefund($order_id, $stock_result[ 'message' ], '订单退款');
  513. if ($refund_result[ 'code' ] < 0) {
  514. model('order')->rollback();
  515. return $refund_result;
  516. }
  517. model('order')->commit();
  518. return $stock_result;
  519. }
  520. }
  521. $goods_virtual_list = model('goods_virtual')->pageList([ [ 'order_id', '=', 0 ], [ 'sku_id', '=', $order_goods_info[ 'sku_id' ] ] ], 'id', 'id asc', 1, $order_goods_info[ 'num' ]);
  522. if (count($goods_virtual_list[ 'list' ]) != $order_goods_info[ 'num' ]) {
  523. model('order')->rollback();
  524. return $this->error('', '卡密库存不足');
  525. }
  526. $ids = array_column($goods_virtual_list[ 'list' ], 'id');
  527. model('goods_virtual')->update([
  528. 'order_id' => $order_id,
  529. 'order_no' => $order_info[ 'order_no' ],
  530. 'member_id' => $order_info[ 'member_id' ],
  531. 'sold_time' => time()
  532. ], [ [ 'id', 'in', $ids ] ]);
  533. // 订单自动收货
  534. $this->orderCommonTakeDelivery($order_id);
  535. model('order')->commit();
  536. return $this->success();
  537. } catch (\Exception $e) {
  538. model('order')->rollback();
  539. return $this->error('', $e->getMessage());
  540. }
  541. }
  542. /**
  543. * 卡项发货设置(需要增加卡项核销)
  544. * @param $order_id
  545. */
  546. public function cardServiceTakeDelivery($order_id)
  547. {
  548. $order_info = model('order')->getInfo([ [ 'order_id', '=', $order_id ] ], 'order_no,site_id,site_name,member_id,order_type,
  549. sign_time,order_status,delivery_code,create_time,name,pay_time,pay_money,mobile,is_lock,order_money');
  550. if (empty($order_info))
  551. return $this->error([], "ORDER_EMPTY");
  552. model('order')->startTrans();
  553. try {
  554. //订单项变为已发货
  555. model('order_goods')->update([ 'delivery_status' => 1, "delivery_status_name" => "已发货" ], [ [ 'order_id', "=", $order_id ] ]);
  556. $order_goods_info = model('order_goods')->getInfo([ [ 'order_id', '=', $order_id ] ], 'sku_id,sku_name,sku_image,price,num,goods_id,order_goods_id');//订单项详情
  557. if (!empty($order_goods_info)) {
  558. $order_goods_info[ 'num' ] = numberFormat($order_goods_info[ 'num' ]);
  559. }
  560. //创建卡项
  561. $member_card = new MemberCard();
  562. $card_data = [
  563. 'store_id' => 0,
  564. 'goods_id' => $order_goods_info[ 'goods_id' ],
  565. 'num' => $order_goods_info[ 'num' ],
  566. 'member_id' => $order_info[ 'member_id' ],
  567. 'site_id' => $order_info[ 'site_id' ],
  568. 'order_id' => $order_id
  569. ];
  570. $res_card = $member_card->create($card_data);
  571. if ($res_card[ 'code' ] < 0) {
  572. model('order')->rollback();
  573. return $this->error('', $res_card[ 'message' ]);
  574. }
  575. // 订单自动收货
  576. $this->orderCommonTakeDelivery($order_id);
  577. model('order')->commit();
  578. return $this->success(1);
  579. } catch (\Exception $e) {
  580. model('order')->rollback();
  581. return $this->error('', $e->getMessage());
  582. }
  583. }
  584. /**
  585. * 自动发货
  586. * @param $order_id
  587. */
  588. public function orderTakeDelivery($order_id)
  589. {
  590. $order_info = model('order')->getInfo([ [ 'order_id', '=', $order_id ] ], 'order_no,site_id,site_name,member_id,order_type,
  591. sign_time,order_status,delivery_code,create_time,name,pay_time,pay_money,mobile,is_lock,order_money');
  592. if (empty($order_info))
  593. return $this->error([], "ORDER_EMPTY");
  594. $res = model('order_goods')->update([ 'delivery_status' => 1, "delivery_status_name" => "已发货" ], [ [ 'order_id', "=", $order_id ] ]);
  595. return $this->success($res);
  596. }
  597. /**
  598. * 退款完成操作
  599. * @param $order_info
  600. */
  601. public function refund($order_goods_info)
  602. {
  603. $virtual_card = ( new \addon\virtualcard\model\VirtualGoods() )->getGoodsClass();
  604. if ($order_goods_info[ 'goods_class' ] != $virtual_card[ 'id' ]) {
  605. //删除已退款订单项会员虚拟商品, 并退回商品库存
  606. //无需判断订单项是否需要入库
  607. $item_param = array (
  608. "sku_id" => $order_goods_info[ "sku_id" ],
  609. "num" => $order_goods_info[ "num" ],
  610. );
  611. //返还库存
  612. $order_stock_model = new OrderStock();
  613. $order_stock_model->incOrderStock($order_goods_info);
  614. //$goods_stock_model->incStock($item_param);
  615. //删除用户的这条虚拟商品
  616. $goods_virtual_model = new VirtualGoods();
  617. $goods_virtual_model->deleteGoodsVirtual([ [ "order_id", "=", $order_goods_info[ "order_id" ] ], [ "member_id", "=", $order_goods_info[ "member_id" ] ] ]);
  618. }
  619. }
  620. /**
  621. * 订单详情
  622. * @param $order_info
  623. */
  624. public function orderDetail($order_info)
  625. {
  626. $verify_record_model = new VerifyRecord();
  627. $data = [
  628. 'goods_class' => $order_info[ 'order_goods' ][ 0 ][ 'goods_class' ]
  629. ];
  630. if ($data[ 'goods_class' ] == 2) {
  631. $virtual_goods = model('goods_virtual')->getFirstData([ [ "order_id", "=", $order_info[ "order_id" ] ] ], '*', 'is_veirfy asc');
  632. if (!empty($virtual_goods)) {
  633. $virtual_goods[ 'total_verify_num' ] = model('goods_virtual')->getCount([ [ "order_id", "=", $order_info[ "order_id" ] ] ]);
  634. $virtual_goods[ 'verify_num' ] = model('goods_virtual')->getCount([ [ "order_id", "=", $order_info[ "order_id" ] ], [ 'is_veirfy', '=', 1 ] ]);
  635. $verify_code = model('goods_virtual')->getColumn([ [ "order_id", "=", $order_info[ "order_id" ] ] ], 'code');
  636. $virtual_goods[ 'verify_record' ] = [];
  637. if (!empty($verify_code)) {
  638. $virtual_goods[ 'verify_record' ] = $verify_record_model->getVerifyRecordsViewList([ [ 'verify_code', 'in', $verify_code ] ], '*', 'verify_time desc')[ 'data' ] ?? [];
  639. }
  640. $data[ "virtual_goods" ] = $virtual_goods;
  641. $data[ "virtual_code" ] = $virtual_goods[ 'code' ];
  642. }
  643. } else if ($data[ 'goods_class' ] == 3) {
  644. $virtual_goods = model('goods_virtual')->getList([ [ "order_id", "=", $order_info[ "order_id" ] ] ], '*', 'id asc');
  645. if (!empty($virtual_goods)) {
  646. foreach ($virtual_goods as $key => $item) {
  647. $virtual_goods[ $key ][ 'card_info' ] = json_decode($item[ 'card_info' ], true);
  648. }
  649. $data[ "virtual_goods" ] = $virtual_goods;
  650. }
  651. }
  652. if ($data[ 'goods_class' ] == 4) {
  653. $virtual_goods = model('goods_virtual')->getFirstData([ [ "order_id", "=", $order_info[ "order_id" ] ] ], '*', 'is_veirfy asc');
  654. if (!empty($virtual_goods)) {
  655. $virtual_goods[ 'total_verify_num' ] = model('goods_virtual')->getCount([ [ "order_id", "=", $order_info[ "order_id" ] ] ]);
  656. $virtual_goods[ 'verify_num' ] = model('goods_virtual')->getCount([ [ "order_id", "=", $order_info[ "order_id" ] ], [ 'is_veirfy', '=', 1 ] ]);
  657. $verify_code = model('goods_virtual')->getColumn([ [ "order_id", "=", $order_info[ "order_id" ] ] ], 'code');
  658. $virtual_goods[ 'verify_record' ] = [];
  659. if (!empty($verify_code)) {
  660. $virtual_goods[ 'verify_record' ] = $verify_record_model->getVerifyRecordsViewList([ [ 'verify_code', 'in', $verify_code ] ], '*', 'verify_time desc')[ 'data' ] ?? [];
  661. }
  662. $data[ "virtual_goods" ] = $virtual_goods;
  663. $data[ "virtual_code" ] = $virtual_goods[ 'code' ];
  664. }
  665. }
  666. return $data;
  667. }
  668. /**
  669. * 虚拟发货
  670. * @param $params
  671. * @return array
  672. */
  673. public function virtualDelivery($params)
  674. {
  675. $order_id = $params[ 'order_id' ] ?? 0;
  676. //todo 核验订单是否处于锁定
  677. $local_result = $this->verifyOrderLock($order_id);
  678. if ($local_result[ 'code' ] < 0)
  679. return $local_result;
  680. $site_id = $params[ 'site_id' ] ?? 0;
  681. $condition = [ [ 'order_id', "=", $params[ 'order_id' ] ] ];
  682. if ($site_id > 0) {
  683. $condition[] = [ 'site_id', '=', $site_id ];
  684. }
  685. $order_info = $this->getOrderInfo($condition)[ 'data' ] ?? [];
  686. if (empty($order_info))
  687. return $this->error([], '找不到订单');
  688. $data = array (
  689. 'order_status' => self::ORDER_DELIVERY,
  690. 'order_status_name' => $this->order_status[ self::ORDER_DELIVERY ][ "name" ],
  691. 'order_status_action' => json_encode($this->order_status[ self::ORDER_DELIVERY ], JSON_UNESCAPED_UNICODE),
  692. );
  693. $res = model('order')->update($data, $condition);
  694. $goods_id = model('order_goods')->getValue([ [ 'order_id', '=', $order_id ] ], 'goods_id');
  695. //判断商品是否需要核销
  696. $goods_info = model('goods')->getInfo([ [ 'goods_id', '=', $goods_id ] ], 'virtual_receive_type');
  697. //增加卡项商品的自动发货
  698. if (!empty($goods_info)) {
  699. $virtual_receive_type = $goods_info[ 'virtual_receive_type' ];
  700. if ($virtual_receive_type == 'auto_receive') {
  701. $result = $this->virtualTakeDelivery($params);
  702. if ($result[ 'code' ] < 0) {
  703. return $result;
  704. }
  705. }
  706. }
  707. return $this->success();
  708. }
  709. public function virtualTakeDelivery($params)
  710. {
  711. $order_id = $params[ 'order_id' ] ?? 0;
  712. $site_id = $params[ 'site_id' ] ?? 0;
  713. $member_id = $params[ 'member_id' ] ?? 0;
  714. $condition = [ [ 'order_id', "=", $order_id ] ];
  715. if ($site_id > 0) {
  716. $condition[] = [ 'site_id', '=', $site_id ];
  717. }
  718. if ($member_id > 0) {
  719. $condition[] = [ 'member_id', '=', $member_id ];
  720. }
  721. $order_info = $this->getOrderInfo($condition)[ 'data' ] ?? [];
  722. if (empty($order_info))
  723. return $this->error([], '找不到订单');
  724. //虚拟产品收货
  725. $result = $this->orderCommonTakeDelivery($order_id);
  726. if ($result[ 'code' ] < 0) {
  727. return $result;
  728. }
  729. return $this->success();
  730. }
  731. /**
  732. * to发送
  733. * @param $params
  734. */
  735. public function toSend($params)
  736. {
  737. $order_id = $params[ 'order_id' ];
  738. $goods_id = model('order_goods')->getValue([ [ 'order_id', '=', $order_id ] ], 'goods_id');
  739. //判断商品是否需要核销
  740. $goods_info = model('goods')->getInfo([ [ 'goods_id', '=', $goods_id ] ], 'goods_class,is_need_verify,virtual_deliver_type');
  741. $order_info = model('order')->getInfo([ [ 'order_id', '=', $order_id ] ]);
  742. if ($goods_info[ 'goods_class' ] == 2) {
  743. switch ( $goods_info[ 'virtual_deliver_type' ] ) {
  744. case 'auto_deliver'://自动发货
  745. $result = $this->virtualDelivery($order_info);//
  746. break;
  747. case 'artificial_deliver'://手动发货
  748. break;
  749. case 'verify'://到店核销
  750. $order_status_item = $this->order_status[ self::ORDER_WAIT_VERIFY ];
  751. $data = array (
  752. 'order_status' => self::ORDER_WAIT_VERIFY,
  753. 'order_status_name' => $order_status_item[ "name" ],
  754. 'order_status_action' => json_encode($order_status_item, JSON_UNESCAPED_UNICODE),
  755. );
  756. $res = model('order')->update($data, [ [ 'order_id', "=", $order_info[ 'order_id' ] ] ]);
  757. if ($goods_info[ 'is_need_verify' ]) {
  758. //虚拟产品发货
  759. $this->virtualOrderTakeDelivery($order_info[ 'order_id' ]);
  760. } else {
  761. //虚拟产品收货
  762. $this->orderCommonTakeDelivery($order_info[ 'order_id' ]);
  763. }
  764. break;
  765. }
  766. } elseif ($goods_info[ 'goods_class' ] == 3) {
  767. $order_status_item = $this->order_status[ self::ORDER_DELIVERY ];
  768. $order_status_item[ 'action' ] = [];
  769. $order_status_item[ 'member_action' ] = [];
  770. $data = array (
  771. 'order_status' => self::ORDER_DELIVERY,
  772. 'order_status_name' => $this->order_status[ self::ORDER_DELIVERY ][ "name" ],
  773. 'order_status_action' => json_encode($order_status_item, JSON_UNESCAPED_UNICODE),
  774. );
  775. $res = model('order')->update($data, [ [ 'order_id', "=", $order_info[ 'order_id' ] ] ]);
  776. // 卡密商品发货
  777. $result = $this->virtualcardTakeDelivery($order_info[ 'order_id' ]);
  778. if ($result[ 'code' ] < 0) {
  779. return $result;
  780. }
  781. } elseif ($goods_info[ 'goods_class' ] == 4) {
  782. $order_status_item = $this->order_status[ self::ORDER_DELIVERY ];
  783. $order_status_item[ 'action' ] = [];
  784. $order_status_item[ 'member_action' ] = [];
  785. $data = array (
  786. 'order_status' => self::ORDER_DELIVERY,
  787. 'order_status_name' => $this->order_status[ self::ORDER_DELIVERY ][ "name" ],
  788. 'order_status_action' => json_encode($order_status_item, JSON_UNESCAPED_UNICODE),
  789. );
  790. $res = model('order')->update($data, [ [ 'order_id', "=", $order_info[ 'order_id' ] ] ]);
  791. $result = $this->serviceGoodsTakeDelivery($order_info[ 'order_id' ]);
  792. if ($result[ 'code' ] < 0) {
  793. return $result;
  794. }
  795. } elseif ($goods_info[ 'goods_class' ] == 5) {
  796. $result = $this->cardServiceTakeDelivery($order_info[ 'order_id' ]);
  797. if ($result[ 'code' ] < 0) {
  798. return $result;
  799. }
  800. }
  801. return $this->success();
  802. }
  803. }