merchant_order.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. <?php
  2. use task\manager;
  3. require_once(BASE_HELPER_PATH . '/task/task_helper.php');
  4. class merchant_orderControl extends mbMerchantControl
  5. {
  6. public function __construct()
  7. {
  8. parent::__construct();
  9. }
  10. public function listOp()
  11. {
  12. $model_vr_order = Model('refill_order');
  13. $cond['mchid'] = $this->mchid();
  14. $cond['inner_status'] = 0;
  15. if (!empty($_GET['card_type'])) {
  16. if(in_array($_GET['card_type'] , ['1' , '2' , '4' , '5' , '6'])) {
  17. $cond['refill_order.card_type'] = $_GET['card_type'];
  18. }
  19. if($_GET['card_type'] == 'oil') {
  20. $cond['refill_order.card_type'] = ['in' , ['1' , '2']];
  21. }
  22. if($_GET['card_type'] == 'phone') {
  23. $cond['refill_order.card_type'] = ['in' , ['4' , '5' , '6']];
  24. }
  25. }
  26. if (!empty($_GET['card_no'])) {
  27. $cond['refill_order.card_no'] = $_GET['card_no'];
  28. }
  29. if (!empty($_GET['refill_amount'])) {
  30. $cond['refill_order.refill_amount'] = $_GET['refill_amount'];
  31. }
  32. if (!empty($_GET['mch_order'])) {
  33. $cond['refill_order.mch_order'] = $_GET['mch_order'];
  34. }
  35. if (!empty($_GET['order_sn'])) {
  36. $cond['refill_order.order_sn'] = $_GET['order_sn'];
  37. }
  38. if (!empty($_GET['quality'])) {
  39. $cond['refill_order.quality'] = $_GET['quality'];
  40. }
  41. $cur_time = time();
  42. $end_date = strtotime(date('Y-m-d',$cur_time));
  43. $add_end = $end_date + 86400 * 5;
  44. $start = intval($_GET['start_time']);
  45. $end = intval($_GET['end_time']);
  46. if($start <= 0) {
  47. $start = $cur_time - 86400 * 2;
  48. }
  49. if($end <= 0) {
  50. $end = $cur_time;
  51. }
  52. $cond['refill_order.order_time'] = [['egt', $start], ['lt', $end], 'and'];
  53. $cond['vr_order.add_time'] = [['egt', $start], ['elt', $add_end], 'and'];
  54. if (in_array($_GET['order_state'], ['0', '30', '40']))
  55. {
  56. $cond['vr_order.order_state'] = $_GET['order_state'];
  57. }
  58. if ($_GET['stat']) {
  59. $stat = $this->orderStatsHour($cond);
  60. return self::outsuccess($stat);
  61. }
  62. $fields = 'refill_order.*,vr_order.order_state';
  63. $total = $this->getTotal($start, $end);
  64. $order_list = $model_vr_order->getMerchantOrderList($cond, $this->page, $total, $fields, 'refill_order.order_time desc');
  65. $order_list = $this->merchant_order_format($order_list);
  66. $result['data'] = $order_list;
  67. $result['total'] = $model_vr_order->gettotalpage();
  68. return self::outsuccess($result);
  69. }
  70. private function getTotal($start,$end)
  71. {
  72. $model_detail = Model('refill_detail');
  73. $cond['order_time'] = [['egt', $start], ['lt', $end], 'and'];
  74. $cond['mchid'] = $this->mchid();
  75. $items= $model_detail->field('count(*) as ncount')->where($cond)->select();
  76. foreach($items as $item) {
  77. $count = intval($item['ncount']);
  78. return $count;
  79. }
  80. return 0;
  81. }
  82. private function orderStatsHour($cond)
  83. {
  84. $stats = Model('')->table('refill_order,vr_order')->join('inner')
  85. ->on('refill_order.order_id=vr_order.order_id')
  86. ->field("FROM_UNIXTIME(order_time,'%d-%H') as hour, count(*) as order_count, sum(refill_amount) as refill_amounts, sum(mch_amount) as mch_amounts, order_state")
  87. ->where($cond)->group('hour, order_state')->select();
  88. $cond['refill_order.channel_name'] = '';
  89. $excp_stats = Model('')->table('refill_order,vr_order')->join('inner')
  90. ->on('refill_order.order_id=vr_order.order_id')
  91. ->field("FROM_UNIXTIME(order_time,'%d-%H') as hour, count(*) as order_count")
  92. ->where($cond)->group('hour')->select();
  93. $data = [];
  94. $except = [];
  95. $result = [];
  96. $all = [
  97. 'success_count' => 0, 'success_amounts' => 0, 'cancel_count' => 0, 'except_count' => 0
  98. ];
  99. if(!empty($excp_stats)) {
  100. foreach ($excp_stats as $value) {
  101. $except[$value['hour']] = $value['order_count'];
  102. }
  103. }
  104. if(!empty($stats)) {
  105. foreach ($stats as $stat) {
  106. $hour = $stat['hour'];
  107. if ($stat['order_state'] == ORDER_STATE_SUCCESS) {
  108. $data[$hour]['success_count'] = $stat['order_count'];
  109. $data[$hour]['success_amounts'] = $stat['refill_amounts'];
  110. } elseif ($stat['order_state'] == ORDER_STATE_CANCEL) {
  111. $data[$hour]['cancel_count'] = $stat['order_count'];
  112. }
  113. if (array_key_exists($hour, $except)) {
  114. $data[$hour]['except_count'] = $except[$hour];
  115. }
  116. }
  117. foreach ($data as $hour => $val) {
  118. $success_count = $val['success_count'] ?? 0;
  119. $success_amounts = $val['success_amounts'] ?? 0;
  120. $cancel_count = $val['cancel_count'] ?? 0;
  121. $except_count = $val['except_count'] ?? 0;
  122. $result[] = [$hour, $success_count, $success_amounts, $cancel_count, $except_count];
  123. $all['success_count'] += $success_count;
  124. $all['success_amounts'] += ncPriceFormat($success_amounts);
  125. $all['cancel_count'] += ncPriceFormat($cancel_count);
  126. $all['except_count'] += ncPriceFormat($except_count);
  127. }
  128. $result[] = ['总计', $all['success_count'], $all['success_amounts'], $all['cancel_count'], $all['except_count']];
  129. }
  130. return $result;
  131. }
  132. public function OrderStatsOp()
  133. {
  134. if(empty($_GET['time_type']) || empty($_GET['start_time']) || empty($_GET['end_time'])) {
  135. return self::outerr(errcode::ErrInputParam, "参数错误.");
  136. }
  137. $cond['inner_status'] = 0;
  138. $time_type = $_GET['time_type'];
  139. $start = $_GET['start_time'];
  140. $end = $_GET['end_time'];
  141. $start_date = strtotime(date('Y-m-d',$start));
  142. $end_date = strtotime(date('Y-m-d',$end));
  143. if ($time_type == 'order_time') {
  144. $add_end = $end_date + 86400 * 5;
  145. $cond['refill_order.order_time'] = [['egt', $start], ['lt', $end], 'and'];
  146. $cond['vr_order.add_time'] = [['egt', $start], ['elt', $add_end], 'and'];
  147. } elseif ($time_type == 'notify_time') {
  148. $add_begin = $start_date - 86400 * 5;
  149. $cond['refill_order.order_time'] = [['egt', $add_begin], ['lt', $end], 'and'];
  150. $cond['vr_order.add_time'] = [['egt', $add_begin], ['elt', $end], 'and'];
  151. $cond['refill_order.notify_time'] = [['egt', $start], ['elt', $end], 'and'];
  152. } else {
  153. return self::outerr(errcode::ErrInputParam, "筛选日期类型错误.");
  154. }
  155. $cond['mchid'] = $this->mchid();
  156. $stats = Model('')->table('refill_order,vr_order')->join('inner')
  157. ->on('refill_order.order_id=vr_order.order_id')
  158. ->field('count(*) as order_count ,sum(refill_amount) as refill_amounts, sum(mch_amount) as mch_amounts, order_state')
  159. ->where($cond)->group('order_state')->select();
  160. $result['count'] = $result['sendCount'] = $result['errorCount'] = $result['successCount'] = $result['refill_amounts'] = $result['mch_amounts'] = 0;
  161. foreach ($stats as $stat) {
  162. $result['count'] += $stat['order_count'];
  163. if($stat['order_state'] == ORDER_STATE_SEND) {
  164. $result['sendCount'] = $stat['order_count'];
  165. }
  166. if($stat['order_state'] == ORDER_STATE_CANCEL) {
  167. $result['errorCount'] = $stat['order_count'];
  168. }
  169. if($stat['order_state'] == ORDER_STATE_SUCCESS) {
  170. $result['successCount'] = $stat['order_count'];
  171. $result['mch_amounts'] = $stat['mch_amounts'];
  172. $result['refill_amounts'] = $stat['refill_amounts'];
  173. }
  174. }
  175. return self::outsuccess($result);
  176. }
  177. private function merchant_order_format($orders)
  178. {
  179. $data = [];
  180. foreach ($orders as $order) {
  181. if($order['notify_time'] > 0)
  182. {
  183. $order['diff_time_text'] = $this->elapse_time($order['notify_time'] - $order['order_time']);
  184. $order['diff_time'] = $order['notify_time'] - $order['order_time'];
  185. }
  186. else
  187. {
  188. $order['diff_time_text'] = $this->elapse_time(time() - $order['order_time']);
  189. $order['diff_time'] = time() - $order['order_time'];
  190. }
  191. if (isset($order['order_time'])) {
  192. $order['order_time'] = date('Y-m-d H:i:s', $order['order_time']);
  193. }
  194. if (isset($order['notify_time'])) {
  195. $order['notify_time'] = date('Y-m-d H:i:s', $order['notify_time']);
  196. }
  197. if($order['is_retrying'] == 1) {
  198. $order['order_state'] = ORDER_STATE_SEND;
  199. }
  200. if ($order['order_state'] == ORDER_STATE_NEW || $order['order_state'] == ORDER_STATE_PAY) {
  201. $order['order_state'] = ORDER_STATE_SEND;
  202. }
  203. $order['order_state_text'] = $this->_orderState($order['order_state']);
  204. $order['card_type_name'] = $this->scard_type($order['card_type']);
  205. $data[] = $order;
  206. }
  207. return $data;
  208. }
  209. /**
  210. * 取得订单状态文字输出形式
  211. *
  212. * @param int $order_state 订单数组
  213. * @return string
  214. */
  215. private function _orderState($order_state)
  216. {
  217. switch ($order_state) {
  218. case ORDER_STATE_CANCEL:
  219. $text = '已取消';
  220. break;
  221. case ORDER_STATE_NEW:
  222. $text = '新订单';
  223. break;
  224. case ORDER_STATE_SEND:
  225. $text = '充值中';
  226. break;
  227. case ORDER_STATE_PAY:
  228. $text = '支付成功';
  229. break;
  230. case ORDER_STATE_SUCCESS:
  231. $text = '充值成功';
  232. break;
  233. case 'retrying':
  234. $text = '重试中';
  235. break;
  236. default:
  237. $text = '未知状态';
  238. }
  239. return $text;
  240. }
  241. private function scard_type(int $card_type)
  242. {
  243. if ($card_type == mtopcard\PetroChinaCard) { //中石油
  244. return '中石油';
  245. } elseif ($card_type == mtopcard\SinopecCard) { //中石化
  246. return '中石化';
  247. } elseif ($card_type == mtopcard\ChinaMobileCard) { //中国移动
  248. return '中国移动';
  249. } elseif ($card_type == mtopcard\ChinaUnicomCard) { //中国联通
  250. return '中国联通';
  251. } elseif ($card_type == mtopcard\ChinaTelecomCard) { //中国电信
  252. return '中国电信';
  253. } elseif ($card_type == mtopcard\ThirdRefillCard) { //中国电信
  254. return '增值业务';
  255. } else {
  256. return 'unknown';
  257. }
  258. }
  259. private function elapse_time($seconds)
  260. {
  261. $minutes = intval($seconds / 60);
  262. $second = intval($seconds % 60);
  263. if($minutes >= 60) {
  264. $minute = $minutes % 60;
  265. $hours = intval($minutes / 60);
  266. $result = "{$minute}:{$second}";
  267. }
  268. else {
  269. if($minutes > 0){
  270. $result = "{$minutes}:{$second}";
  271. }else{
  272. $result = "{$second}";
  273. }
  274. }
  275. if(isset($hours))
  276. {
  277. $result = "{$hours}:" . $result;
  278. }
  279. return $result;
  280. }
  281. public function OrderExportOp()
  282. {
  283. $cond['mchid'] = $this->mchid();
  284. $cond['inner_status'] = 0;
  285. $fSingle = false;
  286. if (!empty($_GET['card_type'])) {
  287. if(in_array($_GET['card_type'] , ['1' , '2' , '4' , '5' , '6'])) {
  288. $cond['refill_order.card_type'] = $_GET['card_type'];
  289. }
  290. if($_GET['card_type'] == 'oil') {
  291. $cond['refill_order.card_type'] = ['in' , ['1' , '2']];
  292. }
  293. if($_GET['card_type'] == 'phone') {
  294. $cond['refill_order.card_type'] = ['in' , ['4' , '5' , '6']];
  295. }
  296. }
  297. if (!empty($_GET['card_no'])) {
  298. $fSingle = true;
  299. $cond['refill_order.card_no'] = $_GET['card_no'];
  300. }
  301. if (!empty($_GET['refill_amount'])) {
  302. $cond['refill_order.refill_amount'] = $_GET['refill_amount'];
  303. }
  304. if (!empty($_GET['mch_order'])) {
  305. $fSingle = true;
  306. $cond['refill_order.mch_order'] = $_GET['mch_order'];
  307. }
  308. if (!empty($_GET['order_sn'])) {
  309. $fSingle = true;
  310. $cond['refill_order.order_sn'] = $_GET['order_sn'];
  311. }
  312. if (!empty($_GET['quality'])) {
  313. $cond['refill_order.quality'] = $_GET['quality'];
  314. }
  315. $cur_time = time();
  316. $end_date = strtotime(date('Y-m-d',$cur_time));
  317. $add_end = $end_date + 86400 * 5;
  318. if($fSingle)
  319. {
  320. $start = intval($_GET['start_time']);
  321. $end = intval($_GET['end_time']);
  322. if($start <= 0) {
  323. $start = $cur_time - 3600;
  324. }
  325. if($end <= 0) {
  326. $end = $cur_time;
  327. }
  328. }
  329. else{
  330. $start = $cur_time - 3600;
  331. $end = $cur_time;
  332. }
  333. $cond['refill_order.order_time'] = [['egt', $start], ['lt', $end], 'and'];
  334. $cond['vr_order.add_time'] = [['egt', $start], ['elt', $add_end], 'and'];
  335. if (in_array($_GET['order_state'], array('0', '30', '40'))) {
  336. $cond['vr_order.order_state'] = $_GET['order_state'];
  337. if($_GET['order_state'] == 30 && $_GET['time'] == 1){
  338. $cond['refill_order.order_time'] = ['lt', (time() - 3600)];
  339. }
  340. }
  341. $order_list = $this->getAllOrders($cond);
  342. $order_list = $this->merchant_order_format($order_list);
  343. $result = $this->export_order_exec($order_list);
  344. return self::outsuccess($result);
  345. }
  346. private function getAllOrders($condition): array
  347. {
  348. $len = 1000;
  349. $i = 0;
  350. $orders = [];
  351. while (true)
  352. {
  353. $start = $i * $len;
  354. $items = Model('')->table('refill_order,vr_order')
  355. ->field('refill_order.*,vr_order.order_state')
  356. ->join('inner')
  357. ->on('refill_order.order_id=vr_order.order_id')
  358. ->where($condition)
  359. ->order('refill_order.order_time desc')
  360. ->limit("{$start},{$len}")
  361. ->select();
  362. $orders = array_merge($orders,$items);
  363. if (empty($items) || count($items) < $len) {
  364. break;
  365. }
  366. $i++;
  367. }
  368. return $orders;
  369. }
  370. private function export_order_exec($order_list)
  371. {
  372. $card_type = ['1'=>'中石油' , '2' =>'中石化' , '4' => '移动' , '5' => '联通' , '6' => '电信'];
  373. $datas = [];
  374. if(defined('COMPANY_NAME') && COMPANY_NAME === 'LZKJ_COMPANY') {
  375. $title = [
  376. ['value' => '代理商账号'],
  377. ['value' => '商品名称'],
  378. ['value' => '交易账号'],
  379. ['value' => '交易金额'],
  380. ['value' => '交易面值'],
  381. ['value' => '交易日期'],
  382. ['value' => '交易状态'],
  383. ['value' => '处理时间'],
  384. ['value' => '第三方流水']
  385. ];
  386. foreach ($order_list as $order) {
  387. $data = [];
  388. $official_sn = $order['official_sn'];
  389. $notify_time = $order['$notify_time'];
  390. if(empty($order['official_sn'])) {
  391. $official_sn = '';
  392. }
  393. if(empty($order['$notify_time'])) {
  394. $notify_time = '';
  395. }
  396. $data[] = ['value' => $order['mchid']];
  397. $data[] = ['value' => "{$card_type[$order['card_type']]}{$order['refill_amount']}元"];
  398. $data[] = ['value' => $order['card_no']];
  399. $data[] = ['value' => $order['mch_amount']];
  400. $data[] = ['value' => $order['refill_amount']];
  401. $data[] = ['value' => $order['order_time']];
  402. $data[] = ['value' => $order['order_state_text']];
  403. $data[] = ['value' => $notify_time];
  404. $data[] = ['value' => $official_sn];
  405. $datas[] = $data;
  406. }
  407. }
  408. else
  409. {
  410. $title = [
  411. ['value' => '商户号'],
  412. ['value' => '客户订单号'],
  413. ['value' => '平台单号'],
  414. ['value' => '面额'],
  415. ['value' => '充值卡号'],
  416. ['value' => '充值卡类型'],
  417. ['value' => '下单日期'],
  418. ['value' => '完成日期'],
  419. ['value' => '官方流水号'],
  420. ['value' => '订单状态'],
  421. ['value' => '扣款金额']
  422. ];
  423. foreach ($order_list as $order) {
  424. $data = [];
  425. $data[] = ['value'=>$order['mchid']];
  426. $data[] = ['value'=>$order['mch_order']];
  427. $data[] = ['value'=>$order['order_sn']];
  428. $data[] = ['value'=>$order['refill_amount']];
  429. $data[] = ['value'=>$order['card_no']];
  430. $data[] = ['value'=>$order['card_type_name']];
  431. $data[] = ['value'=>$order['order_time']];
  432. $data[] = ['value'=>$order['notify_time']];
  433. $data[] = ['value'=>$order['official_sn']];
  434. $data[] = ['value'=>$order['order_state_text']];
  435. $data[] = ['value'=>$order['mch_amount']];
  436. $datas[] = $data;
  437. }
  438. }
  439. return ['title' => $title , 'data' => $datas];
  440. }
  441. private function checkSend($start, $end)
  442. {
  443. $order_state_send = ORDER_STATE_SEND;
  444. $order_state_queue = ORDER_STATE_QUEUE;
  445. $cond['order_state'] = ['in',"{$order_state_send},{$order_state_queue}"];
  446. $cond['order_time'] = [['egt', $start], ['lt', $end], 'and'];
  447. $cond['mchid'] = $this->mchid();
  448. return Model('refill_detail')->where($cond)->select();
  449. }
  450. private function is_timestamp($timestamp) {
  451. $timestamp = intval($timestamp);
  452. if(strtotime(date('Y-m-d H:i:s',$timestamp)) === $timestamp) {
  453. return $timestamp;
  454. } else return false;
  455. }
  456. public function create_taskOp()
  457. {
  458. if(empty($_GET['time_type']) || empty($_GET['start_time']) || empty($_GET['end_time'])) {
  459. return self::outerr(errcode::ErrInputParam, "参数错误.");
  460. }
  461. if(!$this->is_timestamp($_GET['start_time']) || !$this->is_timestamp($_GET['end_time'])) {
  462. return self::outerr(errcode::ErrInputParam, "时间戳类型错误.");
  463. }
  464. $task_title_create = function ($start, $end, $time_type){
  465. $start = date('Y-m-d H:i:s', $start);
  466. $end = date('Y-m-d H:i:s', $end);
  467. if ($time_type === 'order_time') {
  468. $task_title = "订单导出: 下单时间 {$start} - {$end}";
  469. } else {
  470. $task_title = "订单导出: 回调时间 {$start} - {$end}";
  471. }
  472. return $task_title;
  473. };
  474. $time_type = $_GET['time_type'];
  475. $start = $_GET['start_time'];
  476. $end = $_GET['end_time'];
  477. if (!empty($this->checkSend($start, $end))) {
  478. return self::outerr(errcode::ErrInputParam, "还有正在充值中的订单,请稍后再试.");
  479. }
  480. $start_date = strtotime(date('Y-m-d',$start));
  481. $end_date = strtotime(date('Y-m-d',$end));
  482. $today = strtotime(date('Y-m-d',time()));
  483. $tomorrow = $today + 86400;
  484. if ($time_type === 'order_time')
  485. {
  486. $add_end = $end_date + 86400 * 5;
  487. if($add_end > $tomorrow) {
  488. $add_end = $tomorrow;
  489. }
  490. $scope = ['order_time' => [$start, $end], 'add_time' => [$start, $add_end]];
  491. } elseif ($time_type === 'notify_time') {
  492. $add_begin = $start_date - 86400 * 5;
  493. $scope = ['order_time' => [$add_begin, $end], 'add_time' => [$add_begin, $end], 'notify_time' => [$start, $end]];
  494. } else {
  495. return self::outerr(errcode::ErrInputParam, "筛选日期类型错误.");
  496. }
  497. $normal_cond['inner_status'] = 0;
  498. $normal_cond['order_state'] = ORDER_STATE_SUCCESS;
  499. $normal_cond['mchid'] = $this->mchid();
  500. $task_title = $task_title_create($start, $end, $time_type);
  501. $cond = ['normal' => $normal_cond, 'time_scope' => $scope, 'export_type' => 'merchant'];
  502. $manager = new manager();
  503. $task = $manager->add_task('refill_order_export',$cond,1,-1, $task_title, $this->mchid());
  504. $file_path = '';
  505. if ($task->completed() && $task->success()) {
  506. $file_name = $task->result();
  507. $file_path = UPLOAD_SITE_URL . '/' . ATTACH_TASK . DS . $file_name;
  508. }
  509. return self::outsuccess(['file_path' => $file_path]);
  510. }
  511. public function task_listOp()
  512. {
  513. $model = Model('task');
  514. $condition['is_show'] = 1;
  515. $condition['mchid'] = $this->mchid();
  516. $task_list = $model->getList($condition, $this->page, '*', 'add_time desc', 20);
  517. foreach ($task_list as $key => $value)
  518. {
  519. if($value['state'] == 3 && !empty($value['result']))
  520. {
  521. $task_list[$key]['file_path'] = UPLOAD_SITE_URL . '/' . ATTACH_TASK . DS . unserialize($value['result']);
  522. }else{
  523. $task_list[$key]['file_path'] = '';
  524. }
  525. }
  526. $result['data'] = $task_list;
  527. $result['total'] = $model->gettotalpage();
  528. return self::outsuccess($result);
  529. }
  530. }