DataCensusController.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. <?php
  2. namespace backend\modules\mall\controllers;
  3. use backend\controllers\MallController;
  4. use common\enums\AppEnum;
  5. use common\enums\RedisKeyEnum;
  6. use common\enums\StatusEnum;
  7. use common\helpers\ArrayHelper;
  8. use common\helpers\DateHelper;
  9. use common\models\census\CensusMall;
  10. use common\models\census\CensusMallGoods;
  11. use common\models\census\CensusMallRegion;
  12. use common\models\census\CensusMallSingleDay;
  13. use common\models\common\Region;
  14. use common\models\goods\Goods;
  15. class DataCensusController extends MallController
  16. {
  17. public $appId = AppEnum::BACKEND;
  18. public $redis = null;
  19. public function init()
  20. {
  21. parent::init();
  22. $this->redis = \Yii::$app->redis;
  23. }
  24. /**
  25. * @name:
  26. * @msg: 组装 redis key
  27. * @param {string} $key
  28. * @return {*}
  29. */
  30. private function getKey(string $key): string
  31. {
  32. $redis_key = RedisKeyEnum::suffix($key, '', true) . ':' . $this->mall_id;
  33. // $redis_key = RedisKeyEnum::suffix($key, '', true) . ':' . 58;
  34. return $redis_key;
  35. }
  36. /**
  37. * @name:
  38. * @msg: 清洗 && 处理 yii2 redis 客户端拿出来的数据,处理成正常数组
  39. * @param {array} $data
  40. * @param {string} $type
  41. * @return {*}
  42. */
  43. private function purgeRedisRst(array $data, string $type = 'hash', string $field_name = ''): array
  44. {
  45. if (empty($data)) {
  46. return [];
  47. }
  48. $result = [];
  49. if ('hash' == $type) {
  50. foreach ($data as $key => $val) {
  51. if ($key % 2 == 0) {
  52. $keys[] = $val;
  53. } else {
  54. $values[] = $val;
  55. }
  56. }
  57. $result = array_combine($keys, $values);
  58. } elseif ('zset-good' == $type) {
  59. $result = [];
  60. foreach ($data as $dk => $dv) {
  61. if ($dk % 2 == 0) {
  62. $keys[] = $dv;
  63. } else {
  64. $values[] = $dv;
  65. }
  66. }
  67. $arr = array_combine($keys, $values);
  68. foreach ($arr as $ak => $av) {
  69. $a_keys = explode(':', $ak);
  70. $result[] = [
  71. 'goods_id' => $a_keys[1],
  72. $field_name => $av,
  73. ];
  74. }
  75. }
  76. return $result;
  77. }
  78. /**
  79. * @name:
  80. * @msg: 总裁驾驶窗
  81. * @param {*}
  82. * @return {*}
  83. */
  84. public function actionDrivingWindow()
  85. {
  86. if (!\Yii::$app->request->isAjax) {
  87. $is_display = \Yii::$app->request->get('is_display', 1);// 判断跳转是否传参
  88. return $this->render('/census/driving-window', ['is_display' => $is_display]);
  89. }
  90. if (\Yii::$app->request->isGet) {
  91. // 汇总的数据
  92. $window_data_default = [
  93. 'id' => 0,
  94. 'total_users' => 0,
  95. 'total_orders' => 0,
  96. 'total_pay_money' => 0,
  97. 'total_visitors' => 0,
  98. ];
  99. $cache_key_mall = $this->getKey(RedisKeyEnum::CENSUS_MALL);
  100. $window_data = $this->purgeRedisRst($this->redis->hgetall($cache_key_mall), 'hash');
  101. if (empty($window_data)) {
  102. $window_data = CensusMall::find()
  103. ->select(['id', 'total_users', 'total_orders', 'total_pay_money', 'total_visitors'])
  104. ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED])
  105. ->limit(1)
  106. ->asArray()
  107. ->one();
  108. if (empty($window_data)) {
  109. $window_data = $window_data_default;
  110. }
  111. }
  112. $arr = [];
  113. foreach ($window_data_default as $key => $val) {
  114. $arr[$key] = $window_data[$key] ?? 0;
  115. }
  116. $window_data = $arr;
  117. // 今日的数据
  118. $today_data_default = [
  119. 'total_views' => 0,
  120. 'total_users' => 0,
  121. 'add_users' => 0,
  122. 'total_pay_money' => 0,
  123. 'total_visitors' => 0,
  124. ];
  125. $date = date('Y-m-d');
  126. $cache_key_single_day = $this->getKey(RedisKeyEnum::CENSUS_MALL_SINGLE_DATE) . ':' . $date;
  127. $today_data = $this->purgeRedisRst($this->redis->hgetall($cache_key_single_day), 'hash');
  128. if (!empty($today_data)) {
  129. $today_data = array_merge($today_data_default, $today_data);
  130. $today_data['today_new_users'] = $today_data['add_users'];
  131. $today_data['today_total_pay_money'] = $today_data['total_pay_money'];
  132. $today_data['today_total_visitors'] = $today_data['total_visitors'];
  133. } else {
  134. $today_data = CensusMallSingleDay::find()
  135. ->select('total_views,add_users as today_new_users,total_pay_money as today_total_pay_money,total_visitors as today_total_visitors')
  136. ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED, 'date' => $date])
  137. ->limit(1)
  138. ->asArray()
  139. ->one();
  140. if (empty($today_data)) {
  141. $today_data = [
  142. 'total_views' => 0,
  143. 'today_new_users' => 0,
  144. 'today_total_pay_money' => 0,
  145. 'today_total_visitors' => 0,
  146. ];
  147. }
  148. }
  149. // dd($window_data);
  150. $drive_window_datas = array_merge($today_data, $window_data);
  151. return $this->success('success', $drive_window_datas);
  152. } else {
  153. return $this->error('请求方式错误');
  154. }
  155. }
  156. /**
  157. * @name:
  158. * @msg: 流量分析页面
  159. * @param {*}
  160. * @return {*}
  161. */
  162. public function actionFlowanAlyse()
  163. {
  164. if (!\Yii::$app->request->isAjax) {
  165. return $this->render('/census/flow-analyse');
  166. }
  167. if (\Yii::$app->request->isGet) {
  168. /* 流量数据 + 新老客户占比数据 ------ start ---- */
  169. $flow_datas_default = [
  170. 'new_customers' => 0,
  171. 'total_users' => 0,
  172. 'total_visitors' => 0,
  173. 'number_of_orders' => 0,
  174. 'total_pay_people' => 0,
  175. 'total_pay_orders' => 0,
  176. 'total_pay_money' => 0,
  177. 'repurchase_people' => 0,
  178. 'repurchase_money' => 0,
  179. 'share_people' => 0,
  180. 'total_views' => 0,
  181. ];
  182. $cache_key_flow = $this->getKey(RedisKeyEnum::CENSUS_MALL);
  183. $flow_datas = $this->purgeRedisRst($this->redis->hgetall($cache_key_flow), 'hash');
  184. if (empty($flow_datas)) {
  185. $flow_datas = CensusMall::find()
  186. ->select('new_customers,total_users,total_visitors,number_of_orders,total_pay_people,total_pay_orders,total_pay_money,repurchase_people,repurchase_money,share_people,total_views')
  187. ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED])
  188. ->asArray()
  189. ->one();
  190. if (empty($flow_datas)) {
  191. $flow_datas = $flow_datas_default;
  192. }
  193. }
  194. $flow_datas = array_merge($flow_datas_default, $flow_datas);
  195. // dd($flow_datas);
  196. // 访问-支付转化率
  197. if ($flow_datas['total_visitors'] > 0) {
  198. $flow_datas['access_pay_rate'] = bcdiv($flow_datas['total_pay_people'], $flow_datas['total_visitors'], 2);
  199. } else {
  200. $flow_datas['access_pay_rate'] = 0;
  201. }
  202. // 访问-下单转化率
  203. if ($flow_datas['total_visitors'] > 0) {
  204. $flow_datas['access_place_order_rate'] = bcdiv($flow_datas['number_of_orders'], $flow_datas['total_visitors'], 2);
  205. } else {
  206. $flow_datas['access_place_order_rate'] = 0;
  207. }
  208. // 访客占比
  209. if ($flow_datas['total_users'] > 0) {
  210. $flow_datas['visitors_rate'] = bcdiv($flow_datas['total_visitors'], $flow_datas['total_users'], 2);
  211. } else {
  212. $flow_datas['visitors_rate'] = 0;
  213. }
  214. // 新客户占比
  215. if ($flow_datas['total_users'] > 0) {
  216. $flow_datas['new_user_rate'] = bcdiv($flow_datas['new_customers'], $flow_datas['total_users'], 2);
  217. } else {
  218. $flow_datas['new_user_rate'] = 0;
  219. }
  220. // 老客户占比
  221. // if ($flow_datas['total_users'] > 0) {
  222. // $flow_datas['old_user_rate'] = bcdiv($flow_datas['regular_customers'], $flow_datas['total_users'], 2);
  223. // } else {
  224. // $flow_datas['old_user_rate'] = 0;
  225. // }
  226. $flow_datas['old_user_rate'] = bcsub(1, $flow_datas['new_user_rate'], 2);
  227. // dd($flow_datas);
  228. // 客单价
  229. if ($flow_datas['total_pay_money'] == 0 || $flow_datas['total_pay_people'] == 0) {
  230. $flow_datas['customer_unit_price'] = 0;
  231. } else {
  232. $flow_datas['customer_unit_price'] = bcdiv($flow_datas['total_pay_money'], $flow_datas['total_pay_people'], 2);
  233. }
  234. /* 流量数据 + 新老客户占比数据 ------ end ---- */
  235. /* 地区订单数据 ------ start ---- */
  236. $cahce_key_region = $this->getKey(RedisKeyEnum::CENSUS_MALL_REGION);
  237. $region_datas = $this->purgeRedisRst($this->redis->hgetall($cahce_key_region), 'hash');
  238. // dd($region_datas);
  239. if (!empty($region_datas)) {
  240. $arr = [];
  241. $time = time();
  242. foreach ($region_datas as $rk => $rv) {
  243. $total_pay_money = $total_orders = 0;
  244. $strs = explode('_', $rk);
  245. $province_id = array_pop($strs);
  246. if (false !== strpos($rk, 'total_pay_money')) {
  247. $total_pay_money = $rv;
  248. }
  249. if (false !== strpos($rk, 'total_orders')) {
  250. $total_orders = $rv;
  251. }
  252. $arr[$province_id]['id'] = 0;
  253. $arr[$province_id]['province_id'] = $province_id;
  254. if (empty($arr[$province_id]['total_orders'])) {
  255. $arr[$province_id]['total_orders'] = $total_orders;
  256. }
  257. if (empty($arr[$province_id]['total_pay_money'])) {
  258. $arr[$province_id]['total_pay_money'] = $total_pay_money;
  259. }
  260. $arr[$province_id]['updated_at'] = $time;
  261. }
  262. // dd($region_datas, $arr);
  263. $region_datas = array_values($arr);
  264. } else {
  265. $region_datas = CensusMallRegion::find()
  266. ->select('id,province_id,total_orders,total_pay_money,updated_at')
  267. ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED])
  268. ->asArray()
  269. ->all();
  270. }
  271. // dd($region_datas);
  272. $province_ids = array_column($region_datas, 'province_id');
  273. $provinces = Region::find()
  274. ->select('id,name,short_title,areacode,initial')
  275. ->where(['id' => $province_ids, 'level' => 1])
  276. ->asArray()
  277. ->indexBy('id')
  278. ->all();
  279. // 地图数据
  280. $map_order_datas = [];
  281. foreach ($region_datas as &$rval) {
  282. $province = $provinces[$rval['province_id']] ?? [];
  283. $rval['province_name'] = $province['name'] ?? '未知';
  284. $rval['province_short_title'] = $province['short_title'] ?? '';
  285. $rval['areacode'] = $province['areacode'] ?? '';
  286. $rval['initial'] = $province['initial'] ?? '';
  287. $map_order_datas[] = [
  288. 'name' => $province['name'] ?? '',
  289. 'value' => $rval['total_orders'] ?? 0,
  290. ];
  291. }
  292. /* 地区订单数据 ------ end ---- */
  293. /* 商品流量排行榜 ------ start ---- */
  294. $cache_key_good_views_ranking = $this->getKey(RedisKeyEnum::CENSUS_MALL_GOODS_VIEWS);
  295. $good_rankings = $this->purgeRedisRst($this->redis->zrevrange($cache_key_good_views_ranking, 0, -1, 'WITHSCORES'), 'zset-good', 'total_views');
  296. // dd($good_rankings);
  297. if (empty($good_rankings)) {
  298. $good_rankings = CensusMallGoods::find()
  299. ->select('id,goods_id,total_views')
  300. ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED])
  301. ->orderBy('total_views desc')
  302. ->limit(6)
  303. ->asArray()
  304. ->all();
  305. }
  306. if (!empty($good_rankings)) {
  307. $goods_ids = array_column($good_rankings, 'goods_id');
  308. $goods = Goods::find()
  309. ->select('id,goods_name,cover_pic')
  310. ->where(['mall_id' => $this->mall_id, 'id' => $goods_ids])
  311. ->asArray()
  312. ->indexBy('id')
  313. ->all();
  314. foreach ($good_rankings as &$ranking) {
  315. $good = $goods[$ranking['goods_id']] ?? [];
  316. $ranking['goods_name'] = $good['goods_name'] ?? '';
  317. $ranking['cover_pic'] = $good['cover_pic'] ?? '';
  318. }
  319. }
  320. /* 商品流量排行榜 ------ end ---- */
  321. /* 新老客户占比饼图 ------ start ---- */
  322. $pie_chart_datas = [
  323. 'total_users' => $flow_datas['total_users'] ?? 0,
  324. 'names' => ['新客户占比', '老客户占比'],
  325. 'data' => [
  326. bcmul($flow_datas['new_user_rate'], 100, 2),
  327. bcmul($flow_datas['old_user_rate'], 100, 2),
  328. ],
  329. ];
  330. /* 新老客户占比饼图 ------ end ---- */
  331. // dd($flow_datas, $region_datas, $good_rankings);
  332. $data = [
  333. 'flow_datas' => $flow_datas,
  334. 'region_datas' => $region_datas,
  335. 'good_rankings' => $good_rankings,
  336. 'map_order_datas' => $map_order_datas,
  337. 'pie_chart_datas' => $pie_chart_datas,
  338. ];
  339. return $this->success('success', $data);
  340. } else {
  341. return $this->error('请求方式错误');
  342. }
  343. }
  344. /**
  345. * @name:
  346. * @msg: 商品数据统计
  347. * @param {*}
  348. * @return {*}
  349. */
  350. public function actionGoodsStatistics()
  351. {
  352. if (!\Yii::$app->request->isAjax) {
  353. return $this->render('/census/goods-statistics');
  354. }
  355. /* 顶部汇总数据 ---- start ------ */
  356. $cache_key_goods_statistics = $this->getKey(RedisKeyEnum::CENSUS_MALL);
  357. $goods_statistics = $this->purgeRedisRst($this->redis->hgetall($cache_key_goods_statistics), 'hash');
  358. $goods_statistics_default = [
  359. 'id' => 0,
  360. 'goods_total_visitors' => 0,
  361. 'goods_total_views' => 0,
  362. 'total_views' => 0,
  363. 'total_pay_people' => 0,
  364. 'total_pay_money' => 0,
  365. 'goods_listings' => 0,
  366. 'repurchase_people' => 0,
  367. 'repurchase_money' => 0,
  368. 'updated_at' => 0,
  369. ];
  370. if (!empty($goods_statistics)) {
  371. $goods_statistics = array_merge($goods_statistics_default, $goods_statistics);
  372. } else {
  373. $goods_statistics = CensusMall::find()
  374. ->select('id,goods_total_visitors,total_views,total_pay_people,total_pay_money,goods_listings,repurchase_people,repurchase_money,updated_at')
  375. ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED])
  376. ->asArray()
  377. ->one();
  378. if (empty($goods_statistics)) {
  379. $goods_statistics = [
  380. 'id' => 0,
  381. 'goods_total_visitors' => 0,
  382. 'goods_total_views' => 0,
  383. 'total_views' => 0,
  384. 'total_pay_people' => 0,
  385. 'total_pay_money' => 0,
  386. 'goods_listings' => 0,
  387. 'repurchase_people' => 0,
  388. 'repurchase_money' => 0,
  389. 'updated_at' => 0,
  390. ];
  391. }
  392. }
  393. // 客单价
  394. if ($goods_statistics['total_pay_money'] == 0 || $goods_statistics['total_pay_people'] == 0) {
  395. $goods_statistics['customer_unit_price'] = 0;
  396. } else {
  397. $goods_statistics['customer_unit_price'] = bcdiv($goods_statistics['total_pay_money'], $goods_statistics['total_pay_people'], 2);
  398. }
  399. /* 顶部汇总数据 ---- end ------ */
  400. /* 商品排行榜 --- start --- */
  401. $goods_ids = [];
  402. $cache_key_good_views_ranking = $this->getKey(RedisKeyEnum::CENSUS_MALL_GOODS_VIEWS);
  403. $good_views_ranking = $this->purgeRedisRst($this->redis->zrevrange($cache_key_good_views_ranking, 0, 4, 'WITHSCORES'), 'zset-good', 'total_views');
  404. if (empty($good_views_ranking)) {
  405. $good_views_ranking = CensusMallGoods::find()
  406. ->select('goods_id,total_views')
  407. ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED])
  408. ->limit(5)
  409. ->asArray()
  410. ->all();
  411. }
  412. $goods_ids = array_merge($goods_ids, array_column($good_views_ranking, 'goods_id'));
  413. $cahce_key_good_sales_ranking = $this->getKey(RedisKeyEnum::CENSUS_MALL_GOODS_SALES_VOLUME);
  414. $good_sales_ranking = $this->purgeRedisRst($this->redis->zrevrange($cahce_key_good_sales_ranking, 0, 4, 'WITHSCORES'), 'zset-good', 'sales_volumes');
  415. if (empty($good_sales_ranking)) {
  416. $good_sales_ranking = CensusMallGoods::find()
  417. ->select('goods_id,total_sales_volume')
  418. ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED])
  419. ->limit(5)
  420. ->asArray()
  421. ->all();
  422. }
  423. $goods_ids = array_merge($goods_ids, array_column($good_sales_ranking, 'goods_id'));
  424. $cache_key_paymoney = $this->getKey(RedisKeyEnum::CENSUS_MALL_GOODS_PAY_MONEY);
  425. $good_paymoney_ranking = $this->purgeRedisRst($this->redis->zrevrange($cache_key_paymoney, 0, 4, 'WITHSCORES'), 'zset-good', 'pay_amounts');
  426. if (empty($good_paymoney_ranking)) {
  427. $good_sales_ranking = CensusMallGoods::find()
  428. ->select('goods_id,total_pay_money')
  429. ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED])
  430. ->limit(5)
  431. ->asArray()
  432. ->all();
  433. }
  434. $goods_ids = array_merge($goods_ids, array_column($good_sales_ranking, 'goods_id'));
  435. $cache_key_visitors = $this->getKey(RedisKeyEnum::CENSUS_MALL_GOODS_VISITORS);
  436. $good_visitor_ranking = $this->purgeRedisRst($this->redis->zrevrange($cache_key_visitors, 0, 4, 'WITHSCORES'), 'zset-good', 'access_times');
  437. if (empty($good_visitor_ranking)) {
  438. $good_rankings = CensusMallGoods::find()
  439. ->select('goods_id,total_visitors')
  440. ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED])
  441. ->limit(5)
  442. ->asArray()
  443. ->all();
  444. }
  445. $goods_ids = array_unique(array_merge($goods_ids, array_column($good_sales_ranking, 'goods_id')));
  446. $goods = Goods::find()
  447. ->select('id,goods_name,cover_pic')
  448. ->where(['mall_id' => $this->mall_id, 'id' => $goods_ids])
  449. ->asArray()
  450. ->indexBy('id')
  451. ->all();
  452. if (!empty($good_sales_ranking)) {
  453. foreach ($good_sales_ranking as $sk => &$sv) {
  454. if ($sk >= 5) {
  455. break;
  456. }
  457. $good = $goods[$sv['goods_id']] ?? [];
  458. $sv['goods_name'] = $good['goods_name'] ?? '';
  459. $sv['cover_pic'] = $good['cover_pic'] ?? '';
  460. }
  461. } else {
  462. $good_sales_ranking = [];
  463. }
  464. if (!empty($good_views_ranking)) {
  465. foreach ($good_views_ranking as $vk => &$vv) {
  466. if ($vk >= 5) {
  467. break;
  468. }
  469. $good = $goods[$vv['goods_id']] ?? [];
  470. $vv['goods_name'] = $good['goods_name'] ?? '';
  471. $vv['cover_pic'] = $good['cover_pic'] ?? '';
  472. $list[] = $vv;
  473. }
  474. } else {
  475. $good_views_ranking = [];
  476. }
  477. if (!empty($good_paymoney_ranking)) {
  478. foreach ($good_paymoney_ranking as $pk => &$pv) {
  479. if ($pk >= 5) {
  480. break;
  481. }
  482. $good = $goods[$pv['goods_id']] ?? [];
  483. $pv['goods_name'] = $good['goods_name'] ?? '';
  484. $pv['cover_pic'] = $good['cover_pic'] ?? '';
  485. $pv['pay_amounts'] = bcadd($pv['pay_amounts'], 0, 2);
  486. }
  487. } else {
  488. $good_paymoney_ranking = [];
  489. }
  490. if (!empty($good_visitor_ranking)) {
  491. foreach ($good_visitor_ranking as $vik => &$viv) {
  492. if ($vik >= 5) {
  493. break;
  494. }
  495. $good = $goods[$viv['goods_id']] ?? [];
  496. $viv['goods_name'] = $good['goods_name'] ?? '';
  497. $viv['cover_pic'] = $good['cover_pic'] ?? '';
  498. }
  499. } else {
  500. $good_visitor_ranking = [];
  501. }
  502. /* 商品排行榜 --- end --- */
  503. /* 中间部分 GMV 的数据 --- start --- */
  504. $day_numbers = 15;
  505. $date_time = DateHelper::someDays($day_numbers, 'before');
  506. $start_time = $date_time['start'];
  507. $endDate = new \DateTime('yesterday');
  508. $endDate->setTime(23, 59, 59);
  509. $end_time = $endDate->getTimestamp();
  510. $gmv_data = CensusMallSingleDay::find()
  511. ->select('id,total_order_money,date,updated_at')
  512. ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED])
  513. ->andWhere(['and', ['>=', 'created_at', $start_time], ['<', 'created_at', $end_time]])
  514. ->orderBy('updated_at asc')
  515. ->asArray()
  516. ->all();
  517. $keys = [];
  518. $values = [];
  519. for ($j = 0; $j < $day_numbers; $j++) {
  520. $date_timep = DateHelper::someDays($j + 1, 'before');
  521. $keys[] = date('m-d', $date_timep['start']);
  522. }
  523. $keys = array_reverse($keys);
  524. if (!empty($gmv_data)) {
  525. foreach ($gmv_data as $val) {
  526. $k = date('m-d', strtotime($val['date'] . ' 00:00:00'));
  527. $date_data_map[$k] = $val['total_order_money'];
  528. }
  529. foreach ($keys as $v) {
  530. $values[] = $date_data_map[$v] ?? 0;
  531. }
  532. } else {
  533. for ($i = 0; $i < $day_numbers; $i++) {
  534. $values[] = 0;
  535. }
  536. }
  537. $gmvs = [
  538. 'keys' => $keys,
  539. 'values' => $values,
  540. ];
  541. /* 中间部分 GMV 的数据 --- end --- */
  542. $data = [
  543. 'goods_data' => $goods_statistics,
  544. 'access_rankings' => $good_visitor_ranking,
  545. 'paymoney_rankings' => $good_paymoney_ranking,
  546. 'sales_rankings' => $good_sales_ranking,
  547. 'gmvs' => $gmvs,
  548. ];
  549. return $this->success('success', $data);
  550. }
  551. }