Order.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. <?php namespace Seller\Lib;
  2. use Dever;
  3. use Dever\Helper\Str;
  4. class Order
  5. {
  6. # 新增订单
  7. public function add($info, $goods, $sku, $account, $order, $num = 1)
  8. {
  9. /*
  10. $data = Dever::store()->transaction(array($this, 'addAct'), array($info, $goods, $sku, $account, $order, $num), '下单失败');*/
  11. $data = $this->addAct($info, $goods, $sku, $account, $order, $num);
  12. if ($data) {
  13. //\Dever\Helper\Redis::push('submit_' . $data['seller_id'], $data['id']);
  14. \Dever\Helper\Redis::push('submit_' . DEVER_PROJECT, $data['id']);
  15. //Dever::load('info', 'seller')->log($data['seller_id'], $data['id'], $data['price'], 3);
  16. }
  17. return $data;
  18. }
  19. public function addAct($info, $goods, $sku, $account, $order, $num = 1)
  20. {
  21. # 验证规则
  22. /*
  23. $cate = Dever::db('cate', 'goods')->find($goods['cate_id']);
  24. if ($cate && $cate['rule'] && !preg_match($cate['rule'], $account)) {
  25. Dever::error($account . '不符合规则');
  26. }*/
  27. # 验证订单号
  28. /*
  29. $check = Dever::db('order', 'seller')->find(array('seller_id' => $info['id'], 'seller_order_num' => $order));
  30. if ($check) {
  31. Dever::error('订单重复');
  32. }*/
  33. $cash = $this->cash($info['id'], $sku['info_id'], $sku['id'], $sku['value'], $num);
  34. # 开始下单
  35. $data = array();
  36. $data['status'] = 1;
  37. $data['finish'] = 2;
  38. $data['account'] = $account;
  39. $data['cate_id'] = $goods['cate_id'];
  40. $data['goods_id'] = $sku['info_id'];
  41. $data['sku_id'] = $sku['id'];
  42. $data['num'] = $num;
  43. $data['cash'] = $sku['value'];
  44. $data['price'] = $cash;
  45. $data['seller_id'] = $info['id'];
  46. $data['seller_order_num'] = $order;
  47. $data['seller_request'] = json_encode(Dever::input(), JSON_UNESCAPED_UNICODE);
  48. $data['id'] = Dever::db('order', 'seller')->insert($data);
  49. if (!$data['id']) {
  50. Dever::error('下单失败');
  51. }
  52. return $data;
  53. }
  54. public function handle($info, $selected = array())
  55. {
  56. //$data = Dever::store()->transaction(array($this, 'handleAct'), array($info, $selected), '下单失败');
  57. $data = $this->handleAct($info, $selected);
  58. /*
  59. $order = Dever::db('order', 'seller')->find($info['id']);
  60. if ($info['status'] < 10 && $order['status'] >= 10) {
  61. if ($order['status'] == 11) {
  62. # 失败,余额加回来
  63. Dever::load('info', 'seller')->inc($order['seller_id'], $order['price']);
  64. Dever::load('info', 'seller')->log($order['seller_id'], $order['id'], $order['price'], 4);
  65. }
  66. //Dever::db('order_log1', 'seller')->insert($order);
  67. }*/
  68. return $data;
  69. }
  70. public function handleAct($info, $selected = array())
  71. {
  72. $test = Dever::input('test');
  73. if ($test == 1) {
  74. } elseif ($info['status'] >= 10) {
  75. return;
  76. }
  77. $update['status'] = 2;
  78. if (!$info['order_num']) {
  79. $info['order_num'] = $update['order_num'] = $this->createOrder();
  80. }
  81. Dever::db('order', 'seller')->update($info['id'], $update);
  82. $channel_num = 0;
  83. $channel = $this->channel($info['seller_id'], $info['goods_id'], $info['sku_id'], $channel_num, $selected);
  84. if (!$channel) {
  85. return $this->notify($info, '通道未开启', $update);
  86. }
  87. $result = array();
  88. if ($channel['type'] == 1) {
  89. # 通信
  90. # 向渠道发起请求 下单
  91. $param['order_id'] = $info['id'];
  92. $param['order_num'] = $info['order_num'];
  93. $param['account'] = $info['account'];
  94. $param['cash'] = $info['cash'];
  95. $param['num'] = $info['num'];
  96. $param['goods_id'] = $info['goods_id'];
  97. if ($info['other']) {
  98. $info['other'] = Dever::json_decode($info['other']);
  99. $param = array_merge($info['other'], $param);
  100. }
  101. if (isset($channel['goods']['discount']) && $channel['goods']['discount']) {
  102. $param['scash'] = $channel['goods']['discount']*$param['cash'];
  103. }
  104. if (isset($channel['goods']['code']) && $channel['goods']['code']) {
  105. $param['code'] = $channel['goods']['code'];
  106. } else {
  107. $sku = Dever::db('info_sku', 'goods')->find($info['sku_id']);
  108. $param['code'] = $sku['code'];
  109. }
  110. $result = Dever::load('func/api', 'connect')->run(1, $info['cate_id'], $channel, $param);
  111. if ($channel_num > 1 && $result && $result['status'] != 1) {
  112. # 记录渠道错误信息
  113. $selected[$channel['id']] = true;
  114. $order_error_data = Dever::db('order_error', 'seller')->select(array('order_num' => $info['order_num']));
  115. if ($order_error_data) {
  116. foreach ($order_error_data as $k => $v) {
  117. $selected[$v['channel_id']] = true;
  118. }
  119. }
  120. $num = count($selected);
  121. $channel_num = $channel_num - $num;
  122. if ($channel_num > 0) {
  123. $order_error = $this->channel_update($info, $channel, $result);
  124. $order_error['order_num'] = $info['order_num'];
  125. Dever::db('order_error', 'seller')->insert($order_error);
  126. return $this->handleAct($info, $selected);
  127. }
  128. }
  129. } elseif ($channel['type'] == 2) {
  130. # 需要审核
  131. # 获取卡密并占用
  132. $param['seller_id'] = array('in', '-1,' . $info['seller_id']);
  133. $param['channel_id'] = $channel['id'];
  134. $param['goods_id'] = $info['goods_id'];
  135. $param['sku_id'] = $info['sku_id'];
  136. $param['status'] = 1;
  137. $param['use_status'] = 1;
  138. $card = Dever::db('card', 'channel')->select($param, array('order' => 'seller_id desc','limit' => '0, ' . $info['num']), true);
  139. $total = count($card);
  140. if ($total < $info['num']) {
  141. return $this->notify($info, '卡密剩余数量不足', $update);
  142. }
  143. foreach ($card as $k => $v) {
  144. Dever::db('card', 'channel')->update($v['id'], array('use_status' => 3, 'order_id' => $info['id']));
  145. }
  146. $result['status'] = 1;
  147. } elseif ($channel['type'] == 11) {
  148. $result['status'] = 1;
  149. }
  150. $update = $this->channel_update($info, $channel, $result);
  151. if ($result['status'] == 1) {
  152. # 下单成功
  153. Dever::db('order', 'seller')->update($info['id'], $update);
  154. return 'ok';
  155. } else {
  156. # 下单失败
  157. return $this->notify($info, '下单失败', $update);
  158. }
  159. }
  160. public function channel_update($info, $channel, $result)
  161. {
  162. $update = array();
  163. $update['channel_id'] = $channel['id'];
  164. $update['channel_order_date'] = time();
  165. if (isset($result['request'])) {
  166. $update['channel_request'] = json_encode($result['request'], JSON_UNESCAPED_UNICODE);
  167. }
  168. if (isset($result['response'])) {
  169. $update['channel_response'] = json_encode($result['response'], JSON_UNESCAPED_UNICODE);
  170. }
  171. if (isset($channel['goods']['id'])) {
  172. $update['channel_goods_id'] = $channel['goods']['id'];
  173. }
  174. $update['channel_goods_discount'] = $channel['discount'];
  175. if (isset($channel['goods']['discount']) && $channel['goods']['discount']) {
  176. $update['channel_goods_discount'] = $channel['goods']['discount'];
  177. }
  178. if (!$update['channel_goods_discount']) {
  179. $update['channel_goods_discount'] = 1;
  180. }
  181. $update['buy_price'] = round($info['cash'] * $update['channel_goods_discount'], 2) * $info['num'];
  182. return $update;
  183. }
  184. # 向商户发起回调
  185. public function notify($info, $msg, $update = array(), $total = 5, $oper = 1, $table = 'order')
  186. {
  187. $seller = Dever::db('info', 'seller')->find($info['seller_id']);
  188. $status = 11;
  189. if ($msg == 'ok') {
  190. $status = 10;
  191. }
  192. # 获取商户回调地址,向商户发起回调
  193. $seller_request = Dever::json_decode($info['seller_request']);
  194. if (isset($seller_request['notify']) && $seller_request['notify']) {
  195. $notify = $seller_request['notify'];
  196. } else {
  197. $notify = $seller['notify'];
  198. }
  199. if ($notify) {
  200. if ($info['seller_callback'] != 'ok' && $info['seller_callback_num'] <= $total) {
  201. $param = array();
  202. $param['appkey'] = $seller['appkey'];
  203. $param['order_num'] = $info['seller_order_num'];
  204. $param['system_order_num'] = $info['order_num'];
  205. $param['order_status'] = $status;
  206. $param['order_cash'] = $info['cash'];
  207. $param['official_order_num'] = $param['official_msg'] = '';
  208. if (isset($info['official_order_num'])) {
  209. $param['official_order_num'] = $info['official_order_num'];
  210. }
  211. if (isset($info['official_msg'])) {
  212. $param['official_msg'] = $info['official_msg'];
  213. }
  214. if (isset($update['official_order_num'])) {
  215. $param['official_order_num'] = $update['official_order_num'];
  216. }
  217. if (isset($update['official_msg'])) {
  218. $param['official_msg'] = $update['official_msg'];
  219. }
  220. # 反正所有榆钱和沧渤的资源进到系统 流水号只要出我们的系统自动就是89 联通就是10010 电信就是10000(不变的)
  221. # 89+8位随机数字+8位订单日期(比如今天就是20240325)+10位随机
  222. $channel_id = array(5,6,8);
  223. if ($status == 10 && in_array($info['channel_id'], $channel_id)) {
  224. $official_order_num = '';
  225. if ($info['goods_id'] == 1) {
  226. # 移动
  227. //$str = '8913807663202404289794416983';
  228. //$str = '8923656675202405029019879800';
  229. $official_order_num = '89' . rand(10000000, 99999999) . date('Ymd') . rand(1000000000, 9999999999);
  230. } elseif ($info['goods_id'] == 2) {
  231. # 联通
  232. $official_order_num = preg_replace('/^11010/i', '10010', $param['official_order_num']);
  233. }
  234. if ($official_order_num) {
  235. $param['official_order_num'] = $update['official_order_num'] = $official_order_num;
  236. }
  237. }
  238. $param = \Dever\Helper\Secure::get($param, $seller['appsecret']);
  239. $notify = urldecode($notify);
  240. $response = Dever::curl($notify, $param, 'post')->result();
  241. # ok是成功
  242. $update['seller_callback'] = $response;
  243. $update['seller_callback_date'] = time();
  244. $update['seller_callback_num'] = $info['seller_callback_num'] + 1;
  245. }
  246. } else {
  247. $update['seller_callback'] = 'ok';
  248. $update['seller_callback_date'] = time();
  249. $update['seller_callback_num'] = $info['seller_callback_num'] + 1;
  250. }
  251. $id = $info['id'];
  252. if ($info['status'] < 10 && $status >= 10) {
  253. # 订单完成
  254. $info['status'] = $update['status'] = $status;
  255. $update['finish'] = 1;
  256. $update['finish_date'] = time();
  257. $info = array_merge($info, $update);
  258. $this->finish($info, $oper, $table);
  259. }
  260. if (!$info['order_num']) {
  261. $update['order_num'] = $this->createOrder();
  262. }
  263. if ($update) {
  264. Dever::db($table, 'seller')->update($id, $update);
  265. }
  266. return $msg;
  267. }
  268. public function finish($info, $oper = 1, $table = 'order')
  269. {
  270. if ($info['status'] == 10) {
  271. if ($info['channel_id']) {
  272. $channel = Dever::db('info', 'channel')->find($info['channel_id']);
  273. if (!$channel) {
  274. Dever::error('未分配渠道');
  275. }
  276. if ($channel['type'] == 2) {
  277. # 审核通过
  278. $param['order_id'] = $info['id'];
  279. //$param['status'] = 1;
  280. $param['use_status'] = 3;
  281. Dever::db('card', 'channel')->update($param, array('use_status' => 2));
  282. }
  283. }
  284. }
  285. if ($info['status'] == 11) {
  286. if ($info['channel_id']) {
  287. $channel = Dever::db('info', 'channel')->find($info['channel_id']);
  288. if (!$channel) {
  289. Dever::error('未分配渠道');
  290. }
  291. if ($channel['type'] == 2) {
  292. # 审核失败
  293. $param['order_id'] = $info['id'];
  294. //$param['status'] = 1;
  295. $param['use_status'] = 3;
  296. Dever::db('card', 'channel')->update($param, array('use_status' => 1));
  297. }
  298. }
  299. if ($oper == 2) {
  300. $channel_num = Dever::db('channel', 'seller')->count(array('seller_id' => $info['seller_id'], 'goods_id' => $info['goods_id'], 'status' => 1));
  301. if ($channel_num > 1 && $info['channel_id']) {
  302. $info['status'] = 2;
  303. Dever::db($table, 'seller')->update($info['id'], array('status' => 2, 'finish' => 2, 'finish_date' => '0'));
  304. # 记录渠道错误信息
  305. $selected = array();
  306. $selected[$info['channel_id']] = true;
  307. $order_error_data = Dever::db('order_error', 'seller')->select(array('order_num' => $info['order_num']));
  308. if ($order_error_data) {
  309. foreach ($order_error_data as $k => $v) {
  310. $selected[$v['channel_id']] = true;
  311. }
  312. }
  313. $num = count($selected);
  314. $channel_num = $channel_num - $num;
  315. if ($channel_num > 0) {
  316. $order_error = array();
  317. $order_error['order_num'] = $info['order_num'];
  318. $order_error['buy_price'] = $info['buy_price'];
  319. $order_error['channel_id'] = $info['channel_id'];
  320. $order_error['channel_goods_id'] = $info['channel_goods_id'];
  321. $order_error['channel_goods_discount'] = $info['channel_goods_discount'];
  322. $order_error['channel_order_date'] = $info['channel_order_date'];
  323. $order_error['channel_order_num'] = $info['channel_order_num'];
  324. $order_error['channel_request'] = $info['channel_request'];
  325. $order_error['channel_response'] = $info['channel_response'];
  326. $order_error['channel_callback'] = $info['channel_callback'];
  327. $order_error['channel_callback_date'] = time();
  328. Dever::db('order_error', 'seller')->insert($order_error);
  329. return Dever::load('order', 'seller')->handleAct($info, $selected);
  330. }
  331. }
  332. }
  333. # 失败,余额加回来
  334. Dever::load('info', 'seller')->inc($info['seller_id'], $info['price']);
  335. //Dever::load('info', 'seller')->log($info['seller_id'], $info['id'], $info['price'], 4);
  336. if ($table == 'order') {
  337. $id = $info['id'];
  338. unset($info['id']);
  339. $state = Dever::db('order_log2', 'seller')->insert($info);
  340. if ($state) {
  341. Dever::db($table, 'seller')->delete($id);
  342. }
  343. }
  344. }
  345. /*
  346. $order_log = Dever::db('order_log', 'seller')->find(array('order_num' => $info['order_num']));
  347. if (!$order_log) {
  348. Dever::db('order_log', 'seller')->insert($info);
  349. }*/
  350. /*
  351. $order_log = Dever::db('order_log1', 'seller')->find(array('order_num' => $info['order_num']));
  352. if (!$order_log) {
  353. Dever::db('order_log1', 'seller')->insert($info);
  354. }*/
  355. }
  356. # 扣费
  357. public function cash($seller_id, $goods_id, $sku_id, $value, $num = 1)
  358. {
  359. if (!$value || $value <= 0) {
  360. Dever::error('面值无效');
  361. }
  362. # 查询折扣 扣费
  363. $seller_goods = Dever::db('goods', 'seller')->find(array('seller_id' => $seller_id, 'goods_id' => $goods_id, 'sku_id' => $sku_id));
  364. if (!$seller_goods) {
  365. $seller_goods = Dever::db('goods', 'seller')->find(array('seller_id' => $seller_id, 'goods_id' => $goods_id, 'sku_id' => -1));
  366. }
  367. $info = Dever::db('info', 'seller')->find($seller_id);
  368. if ($seller_goods && $seller_goods['discount']) {
  369. $info['discount'] = $seller_goods['discount'];
  370. }
  371. if (!$info['discount']) {
  372. $info['discount'] = 1;
  373. }
  374. $cash = round($value * $info['discount'], 2) * $num;
  375. # 查询余额是否充足
  376. $info['yue'] = $info['credit'] + $info['cash'];
  377. if ($info['yue'] < $cash) {
  378. Dever::error('余额不足');
  379. }
  380. $state = Dever::load('info', 'seller')->dec($info['id'], $cash);
  381. if (!$state) {
  382. Dever::error('余额不足');
  383. }
  384. return $cash;
  385. }
  386. # 获取渠道
  387. public function channel($seller_id, $goods_id, $sku_id, &$channel_num, $selected = array())
  388. {
  389. # 查找渠道
  390. $channel_list = Dever::db('channel', 'seller')->select(array('seller_id' => $seller_id, 'goods_id' => $goods_id, 'status' => 1));
  391. if (!$channel_list) {
  392. return false;
  393. }
  394. $channel_num = count($channel_list);
  395. $max = 1;
  396. $channel = $goods = array();
  397. foreach ($channel_list as $k => $v) {
  398. if ($selected && isset($selected[$v['channel_id']])) {
  399. continue;
  400. }
  401. if (!$v['sku_id']) {
  402. $goods = Dever::db('goods', 'channel')->find(array('channel_id' => $v['channel_id'], 'goods_id' => $goods_id, 'sku_id' => $sku_id));
  403. if ($goods) {
  404. $channel = $v['channel_id'];
  405. $max = $v['max'];
  406. break;
  407. } else {
  408. $goods = Dever::db('goods', 'channel')->find(array('channel_id' => $v['channel_id'], 'goods_id' => $goods_id, 'sku_id' => -1));
  409. if ($goods) {
  410. $channel = $v['channel_id'];
  411. $max = $v['max'];
  412. break;
  413. }
  414. }
  415. } else {
  416. $all_sku_id = explode(',', $v['sku_id']);
  417. if (in_array($sku_id, $all_sku_id)) {
  418. $channel = $v['channel_id'];
  419. $max = $v['max'];
  420. $goods = Dever::db('goods', 'channel')->find(array('channel_id' => $v['channel_id'], 'goods_id' => $goods_id, 'sku_id' => $sku_id));
  421. if (!$goods) {
  422. $goods = Dever::db('goods', 'channel')->find(array('channel_id' => $v['channel_id'], 'goods_id' => $goods_id, 'sku_id' => -1));
  423. }
  424. break;
  425. }
  426. }
  427. }
  428. if (!$channel) {
  429. return false;
  430. }
  431. $channel = Dever::db('info', 'channel')->find($channel);
  432. if (!$channel) {
  433. return false;
  434. }
  435. if ($channel['status'] == 2) {
  436. return false;
  437. }
  438. $channel['goods'] = $goods;
  439. $channel['max'] = $max;
  440. return $channel;
  441. }
  442. public function createOrder()
  443. {
  444. $where['order_num'] = Str::order('C');
  445. $state = Dever::db('order', 'seller')->find($where);
  446. if (!$state) {
  447. return $where['order_num'];
  448. } else {
  449. return $this->createOrder();
  450. }
  451. }
  452. }