StatisticsController.php 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085
  1. <?php
  2. namespace backend\modules\mall\controllers;
  3. use backend\controllers\MallController;
  4. use backend\modules\mall\services\LevelService;
  5. use backend\modules\mall\services\StatisticsService;
  6. use backend\modules\mall\services\TeamService;
  7. use common\enums\RabbitMqEnum;
  8. use common\helpers\DateHelper;
  9. use common\logic\statistics\UserTeamStatisticsLogic;
  10. use common\models\census\CensusMall;
  11. use common\models\census\CensusMallGoods;
  12. use common\models\census\CensusMallSingleDay;
  13. use common\models\census\CensusMallSingleHour;
  14. use common\models\census\CensusMallUser;
  15. use common\models\common\Region;
  16. use common\models\statistics\GlobalStatistics;
  17. use common\models\statistics\UserStatistics;
  18. use common\models\statistics\GoodsStatistics;
  19. use common\models\statistics\RegionStatistics;
  20. use common\models\user\User;
  21. use common\models\goods\Goods;
  22. use common\enums\DownloadEnum;
  23. use common\enums\RedisKeyEnum;
  24. use common\helpers\csv\CsvExportHelper;
  25. use common\models\user\UserPartitionRelationship;
  26. use common\models\user\UserLevel;
  27. use common\enums\StatusEnum;
  28. use common\models\common\MallSetting;
  29. use common\models\order\Order;
  30. use Yii;
  31. use common\models\user\UserTeamStatistics;
  32. class StatisticsController extends MallController
  33. {
  34. public $enableCsrfValidation = false;
  35. /**
  36. *
  37. * 数据概况
  38. */
  39. public function actionDataStatisticsOld() {
  40. if (Yii::$app->request->isAjax) {
  41. //用户数
  42. $redis_key = RedisKeyEnum::suffix(RedisKeyEnum::CENSUS_MALL, '', true) . ':' . $this->mall_id;
  43. $userNum = Yii::$app->redis->hget($redis_key,'total_users');
  44. if(empty($userNum)){
  45. $census_mall = CensusMall::findOne(['mall_id'=>$this->mall_id,'status' => StatusEnum::ENABLED]);
  46. $userNum = $census_mall['total_users'];
  47. }
  48. $post = Yii::$app->request->post();
  49. $goodsParam['where'][] = ['=', 'mall_id', $this->mall_id];
  50. if (isset($post['date_start']) && !empty($post['date_start']) && isset($post['date_end']) && !empty($post['date_end'])) {
  51. $goodsParam['where'][] = ['>=', 'created_at', strtotime($post['date_start'] . '0:0:0')];
  52. $goodsParam['where'][] = ['<=', 'created_at', strtotime($post['date_end'] . '23:59:59')];
  53. $startTime = implode('', explode('-', $post['date_start']));
  54. $endTime = implode('', explode('-', $post['date_end']));
  55. if ($startTime === $endTime) {
  56. $params['where'][] = ['=', 'date', $startTime];
  57. } else {
  58. $params['where'][] = ['>=', 'date', $startTime];
  59. $params['where'][] = ['<=', 'date', $endTime];
  60. }
  61. }
  62. $params['where'][] = ['=', 'mall_id', $this->mall_id];
  63. $goodsNum = Goods::count($goodsParam);
  64. if (!$goodsNum) $goodsNum = 0;
  65. //用户数,商品数,订单数,代发货订单数,售后订单数
  66. $orderStatistics = UserStatistics::getOrderStatistics(
  67. $params,
  68. ['sum(order_num) order_num', 'sum(refund_order_num) pro_order'],
  69. 'mall_id'
  70. );
  71. $orderStatistics['order_num'] = $orderStatistics[0]['order_num'] ?? 0;
  72. $orderStatistics['pro_order'] = $orderStatistics[0]['pro_order'] ?? 0;
  73. unset($orderStatistics[0]);
  74. $orderStatistics['user_count'] = $userNum;
  75. $orderStatistics['goods_num'] = $goodsNum;
  76. return $this->success('操作成功', $orderStatistics);
  77. }
  78. return $this->render('data-tatistics');
  79. }
  80. public function actionDataStatistics() {
  81. if (Yii::$app->request->isAjax) {
  82. //用户数
  83. $redis_key = RedisKeyEnum::suffix(RedisKeyEnum::CENSUS_MALL, '', true) . ':' . $this->mall_id;
  84. $userNum = Yii::$app->redis->hget($redis_key,'total_users');
  85. if(empty($userNum)){
  86. $census_mall = CensusMall::findOne(['mall_id'=>$this->mall_id,'status' => StatusEnum::ENABLED]);
  87. $userNum = $census_mall['total_users'];
  88. }
  89. $post = Yii::$app->request->post();
  90. $params = [];
  91. $where[] = ['mall_id'=>$this->mall_id];
  92. if ( !empty($post['date_start']) && !empty($post['date_end'])) {
  93. $where[] = ['>=', 'created_at', strtotime($post['date_start'] . ' 00:00:00')];
  94. $where[] = ['<=', 'created_at', strtotime($post['date_end'] . '23:59:59')];
  95. }
  96. $params['where'] = $where;
  97. $params['select'] = 'sum(add_goods) as add_goods,sum(add_users) as add_users,sum(add_orders) as add_orders,sum(add_refund_orders) as add_refund_orders';
  98. $result = CensusMallSingleDay::lists($params);
  99. $orderStatistics['order_num'] = 0;
  100. $orderStatistics['pro_order'] = 0;
  101. $orderStatistics['user_count'] = $userNum;
  102. $orderStatistics['goods_num'] = 0;
  103. $orderStatistics['user_count'] = $orderStatistics['user_count'] ?: 0;
  104. if(!empty($result[0])){
  105. $orderStatistics['order_num'] = $result[0]['add_orders'] ? :0;
  106. $orderStatistics['pro_order'] = $result[0]['add_refund_orders'] ?: 0;
  107. $orderStatistics['goods_num'] =$result[0]['add_goods'] ?:0;
  108. }
  109. return $this->success('操作成功', $orderStatistics);
  110. }
  111. return $this->render('data-tatistics');
  112. }
  113. /**
  114. * 销售情况
  115. */
  116. public function actionSaleInfoOld() {
  117. //销售情况
  118. $day = Yii::$app->request->post('day');
  119. $day = $day ?? 1;
  120. $start_date = strtotime("-$day day 0:0:0");
  121. $end_date = strtotime("-1 day 23:59:59");
  122. $params['where'][] = ['>=', 'created_at', $start_date];
  123. $params['where'][] = ['<=', 'created_at', $end_date];
  124. $params['where'][] = ['=', 'mall_id', $this->mall_id];
  125. $saleList = UserStatistics::getOrderStatistics($params, ['created_at', 'pay_num', 'pay_money', 'pay_goods_num']);
  126. $saleInfo = [
  127. 'user_count' => 0, //支付人数
  128. 'order_num' => 0, //支付订单数
  129. 'total_pay_price' => 0, //支付金额
  130. 'goods_num' => 0 //支付件数
  131. ];
  132. $arr = [];
  133. foreach ($saleList as $item) {
  134. //筛选昨日按照每小时数量分组,筛选七日按照每日数据分组
  135. if ($day == 7) {
  136. $date = date('Y-m-d', $item['created_at']);
  137. } else {
  138. $date = intval(date('H', $item['created_at']));
  139. }
  140. if (isset($arr[$date])) {
  141. $arr[$date]['user_num'] += $item['pay_money'] > 0 ? 1: 0;
  142. $arr[$date]['order_num'] += $item['pay_num'] ?? 0;
  143. $arr[$date]['total_pay_price'] += $item['pay_money'] ?? 0;
  144. $arr[$date]['goods_num'] += $item['pay_goods_num'] ?? 0;
  145. } else {
  146. $arr[$date]['created_at'] = $day == 7 ? $date : $date.":00";
  147. $arr[$date]['user_num'] = $item['pay_money'] > 0 ? 1: 0;
  148. $arr[$date]['order_num'] = $item['pay_num'] ?? 0;
  149. $arr[$date]['total_pay_price'] = $item['pay_money'] ?? 0;
  150. $arr[$date]['goods_num'] = $item['pay_goods_num'] ?? 0;
  151. }
  152. $saleInfo['user_count'] += $item['pay_money'] > 0 ? 1: 0;
  153. $saleInfo['order_num'] += $item['pay_num'] ?? 0;
  154. $saleInfo['total_pay_price'] += $item['pay_money'] ?? 0;
  155. $saleInfo['goods_num'] += $item['pay_goods_num'] ?? 0;
  156. }
  157. if ($day == 1) {
  158. for ($i = 0; $i < 24; $i++) {
  159. if (!isset($arr[$i])) {
  160. $arr[$i] = ['created_at' => $i.':00', 'user_num' => 0, 'order_num' => 0, 'total_pay_price' => 0, 'goods_num' => 0];
  161. }
  162. }
  163. ksort($arr);
  164. } else {
  165. $temp = [];
  166. for ($i = 0; $i < 7; $i++) {
  167. $date = $start_date + ($i * 86400);
  168. $date = date('Y-m-d', $date);
  169. if (isset($arr[$date])) {
  170. $temp[] = $arr[$date];
  171. } else {
  172. $temp[] = ['created_at' => $date, 'user_num' => 0, 'order_num' => 0, 'total_pay_price' => 0, 'goods_num' => 0];
  173. }
  174. }
  175. $arr = $temp;
  176. }
  177. return $this->success('操作成功', ['table_list' => $arr, 'table_data' => $saleInfo]);
  178. }
  179. public function actionSaleInfo() {
  180. //销售情况
  181. $day = Yii::$app->request->get('day');
  182. $day = $day ?? 1;
  183. $start_date = strtotime("-$day day 0:0:0");
  184. $params = [];
  185. if($day==1){
  186. $params['where'][] = ['=', 'mall_id', $this->mall_id];
  187. $params['where'][] = ['=', 'date', date('Y-m-d',strtotime("-1 day"))];
  188. $list = CensusMallSingleHour::lists($params);
  189. $one_day = CensusMallSingleDay::getOne([
  190. ['mall_id'=> $this->mall_id],
  191. ['date'=>date('Y-m-d',strtotime("-1 day"))]
  192. ]);
  193. $user_count = $one_day['add_pay_people_nums']??0;
  194. $order_num = $one_day['add_pay_orders']??0;
  195. $total_pay_price = $one_day['total_pay_money']??0;
  196. $add_pay_nums = $one_day['add_pay_nums']??0;
  197. $saleInfo = [
  198. 'user_count' => $user_count, //支付人数
  199. 'order_num' => $order_num, //支付订单数
  200. 'total_pay_price' => $total_pay_price, //支付金额
  201. 'goods_num' => $add_pay_nums //支付件数
  202. ];
  203. $list = array_column($list,null,'hour');
  204. $arr = [];
  205. for ($i = 0; $i < 24; $i++) {
  206. $k = $i;
  207. if($i<10) $k='0'.$i;
  208. if (!isset($list[$k])) {
  209. $arr[$i] = ['created_at' => $i.':00', 'user_num' => 0, 'order_num' => 0, 'total_pay_price' => 0, 'goods_num' => 0];
  210. }else{
  211. $arr[$i] = ['created_at' => $i.':00', 'user_num' => $list[$k]['add_pay_people_nums'],
  212. 'order_num' => $list[$k]['add_pay_orders'], 'total_pay_price' => $list[$k]['total_pay_money'],
  213. 'goods_num' => $list[$k]['add_pay_nums']];
  214. }
  215. }
  216. }else{
  217. $dates = [];
  218. for ($i=0;$i<$day;$i++){
  219. $dates[] = date('Y-m-d',strtotime("-$i day"));
  220. }
  221. $params['where'][] = ['=', 'mall_id', $this->mall_id];
  222. $params['where']['date'] = ['in', 'date',$dates];
  223. $list = CensusMallSingleDay::lists($params);
  224. $user_count = array_sum(array_column($list,'add_pay_people_nums'));
  225. $order_num = array_sum(array_column($list,'add_pay_orders'));
  226. $total_pay_price = array_sum(array_column($list,'total_pay_money'));
  227. $add_pay_nums = array_sum(array_column($list,'add_pay_nums'));
  228. $saleInfo = [
  229. 'user_count' => $user_count, //支付人数
  230. 'order_num' => $order_num, //支付订单数
  231. 'total_pay_price' => $total_pay_price, //支付金额
  232. 'goods_num' => $add_pay_nums //支付件数
  233. ];
  234. $list = array_column($list,null,'date');
  235. $temp = [];
  236. for ($i = 0; $i < 7; $i++) {
  237. $date = $start_date + ($i * 86400);
  238. $date = date('Y-m-d', $date);
  239. if (isset($list[$date])) {
  240. $temp[] = ['created_at' => $date,
  241. 'user_num' => $list[$date]['add_pay_people_nums'],
  242. 'order_num' => $list[$date]['add_pay_orders'],
  243. 'total_pay_price' => $list[$date]['total_pay_money'],
  244. 'goods_num' => $list[$date]['add_pay_nums']
  245. ];
  246. } else {
  247. $temp[] = ['created_at' => $date, 'user_num' => 0, 'order_num' => 0, 'total_pay_price' => 0, 'goods_num' => 0];
  248. }
  249. }
  250. $arr = $temp;
  251. }
  252. return $this->success('操作成功', ['table_list' => $arr, 'table_data' => $saleInfo]);
  253. }
  254. /**
  255. * 数据概况-排行榜
  256. * data['user_rank'] 用户购买力TOP排行
  257. * data['goods_rank'] 商品购买力TOP排行
  258. * @return void
  259. */
  260. public function actionTopRankOld() {
  261. $userRank = [];
  262. $goodsRank = [];
  263. $get = Yii::$app->request->get();
  264. if ((!isset($get['order_type']) || empty($get['order_type'])) || (isset($get['order_type']) && $get['order_type'] == 'user_rank')) {
  265. $order = isset($get['order_by']) && !empty($get['order_by']) ? $get['order_by'] : 'pay_money desc';
  266. $param['where']=[['mall_id' => $this->mall_id]];
  267. $userRank = UserStatistics::getOrderStatistics($param, ['user_id', 'sum(pay_money) as pay_money', 'sum(pay_goods_num) as pay_goods_num'], 'user_id', 10, $order);
  268. $user_id = array_column($userRank, 'user_id');
  269. $userList = User::find()->where(['id' => $user_id])->select(['avatar_url','nickname','id'])->indexBy('id')->asArray()->all();
  270. foreach ($userRank as &$goods) {
  271. if (isset($userList[$goods['user_id']]['avatar_url'])) {
  272. $goods['avatar_url'] = $userList[$goods['user_id']]['avatar_url'];
  273. } else {
  274. $goods['avatar_url'] = '';
  275. }
  276. if (isset($userList[$goods['user_id']]['nickname'])) {
  277. $goods['nickname'] = $userList[$goods['user_id']]['nickname'];
  278. } else {
  279. $goods['nickname'] = '';
  280. }
  281. }
  282. }
  283. if((!isset($get['order_type']) || empty($get['order_type'])) || (isset($get['order_type']) && $get['order_type'] == 'goods_rank')){
  284. $orderBy = 'sales_num';
  285. $stor = 'desc';
  286. $redis = \Yii::$app->redis;
  287. if (isset($get['order_by']) && !empty($get['order_by'])) {
  288. $orderBy = explode(' ', $get['order_by'])[0];
  289. $stor = explode(' ', $get['order_by'])[1];
  290. }
  291. $stor = strtolower($stor);
  292. $orderBy = strtolower($orderBy);
  293. $goodsRank = Yii::$app->services->statistics->goods->get($this->mall_id, $stor, $orderBy);
  294. if (!empty($goodsRank)) {
  295. foreach ($goodsRank as &$goods) {
  296. //如果支付金额排序关联销售数量,如果销售数量排序关联金额
  297. if ($orderBy == 'pay_money') {
  298. $goods['sales_num'] = $redis->zscore(RedisKeyEnum::suffix(RedisKeyEnum::GOODS_STATISTICS_SALE, 'mall_id_'. $this->mall_id), 'goods_id:' . $goods['goods_id']) ?? 0;;
  299. } else {
  300. $goods['pay_money'] = $redis->zscore(RedisKeyEnum::suffix(RedisKeyEnum::GOODS_STATISTICS_MONEY, 'mall_id_' . $this->mall_id), 'goods_id:' . $goods['goods_id']) ?? 0;
  301. }
  302. }
  303. }
  304. }
  305. $data['user_rank'] = empty($userRank) ? [] : array_values($userRank);
  306. $data['goods_rank'] = empty($goodsRank) ? [] : array_values($goodsRank);
  307. return $this->success('操作成功', $data);
  308. }
  309. public function actionTopRank() {
  310. $get = Yii::$app->request->get();
  311. if ((!isset($get['order_type']) || empty($get['order_type'])) || (isset($get['order_type']) && $get['order_type'] == 'user_rank')) {
  312. $where = [];
  313. $where[]=['mall_id'=>$this->mall_id];
  314. $params['where'] = $where;
  315. $params['limit'] = 10;
  316. $order = 'total_pay_money desc';
  317. if (!empty($get['order_by'])) {
  318. $arr = explode(' ', $get['order_by']);
  319. $orderBy =$arr[0];
  320. $field = 'total_pay_money';
  321. if($orderBy=='pay_money') $field = 'total_pay_money';
  322. if($orderBy=='sales_num ') $field = 'total_pay_money';
  323. $sort = $arr[1];
  324. $order = $field. ' '.$sort;
  325. }
  326. $params['order'] = $order;
  327. $user_list = CensusMallUser::lists($params);
  328. if(!empty($user_list)){
  329. $user_ids = array_column($user_list,'user_id');
  330. $user_arr = User::find()->where(['id' => $user_ids])->select(['avatar_url','nickname','id'])->indexBy('id')->asArray()->all();
  331. foreach ($user_list as &$item){
  332. $item['avatar_url'] = '';
  333. $item['nickname'] = '';
  334. $item['pay_money'] = $item['total_pay_money'];
  335. $item['pay_goods_num'] = $item['add_pay_nums'];
  336. if(isset($user_arr[$item['user_id']])){
  337. $item['avatar_url'] = $user_arr[$item['user_id']]['avatar_url'];
  338. $item['nickname'] = $user_arr[$item['user_id']]['nickname'];
  339. }
  340. }
  341. }
  342. }
  343. if((!isset($get['order_type']) || empty($get['order_type'])) || (isset($get['order_type']) && $get['order_type'] == 'goods_rank')){
  344. $where = [];
  345. $where[]=['mall_id'=>$this->mall_id];
  346. $params['where'] = $where;
  347. $params['limit'] = 10;
  348. $order = 'total_sales_volume desc';
  349. if (!empty($get['order_by'])) {
  350. $arr = explode(' ', $get['order_by']);
  351. $orderBy =$arr[0];
  352. $field = 'total_pay_money';
  353. if($orderBy=='pay_money') $field = 'total_pay_money';
  354. if($orderBy=='sales_num ') $field = 'total_sales_volume';
  355. $sort = $arr[1];
  356. $order = $field. ' '.$sort;
  357. }
  358. $params['order'] = $order;
  359. $list = CensusMallGoods::lists($params);
  360. if(!empty($list)){
  361. $goods_ids = array_column($list,'goods_id');
  362. $goods_list = Goods::lists(['where'=>[['mall_id'=>$this->mall_id],['id'=>$goods_ids]],'index'=>'id']);
  363. foreach ($list as &$item){
  364. $item['cover_pic'] = '';
  365. $item['goods_name'] = '';
  366. $item['pay_money'] = $item['total_pay_money'];
  367. $item['sales_num'] = $item['total_sales_volume'];
  368. if(isset($goods_list[$item['goods_id']])){
  369. $item['goods_name'] = $goods_list[$item['goods_id']]['goods_name'];
  370. $item['cover_pic'] = $goods_list[$item['goods_id']]['cover_pic'];
  371. }
  372. }
  373. }
  374. }
  375. // $data['user_rank'] = empty($userRank) ? [] : array_values($userRank);
  376. $data['user_rank'] = empty($user_list) ? [] : $user_list;
  377. $data['goods_rank'] = empty($list) ? [] : $list;
  378. return $this->success('操作成功', $data);
  379. }
  380. /**
  381. * 销售数据
  382. */
  383. public function actionSaleStatisticsOld() {
  384. if (\Yii::$app->request->isAjax) {
  385. $params = Yii::$app->request->get();
  386. $where['where'][] = ['=', 'mall_id', $this->mall_id];
  387. if (isset($params['pay_type']) && !empty($params['pay_type']) && $params['pay_type'] == 'wechat') $where['where'][] = ['>', 'wechat_pay', 0];
  388. if (isset($params['pay_type']) && !empty($params['pay_type']) && $params['pay_type'] == 'balance') $where['where'][] = ['>', 'balance_pay', 0];
  389. if (isset($params['date_start']) && !empty($params['date_start']) && isset($params['date_end']) && !empty($params['date_end'])) {
  390. $startTime = implode('', explode('-', $params['date_start']));
  391. $endTime = implode('', explode('-', $params['date_end']));
  392. $where['where'][] = ['>=', 'date', $startTime];
  393. $where['where'][] = ['<=', 'date', $endTime];
  394. }
  395. $where['select'] = ['date', 'count(user_id) user_num'];
  396. //已完成订单数
  397. if ($params['status'] == 1) {
  398. array_push($where['select'], 'sum(finish_order_num) order_num', 'sum(finish_order_money) order_money', 'sum(finish_goods_num) goods_num');
  399. $where['where'][] = ['>', 'finish_order_num', 0];
  400. }
  401. //已取消订单数
  402. if ($params['status'] == 2) {
  403. array_push($where['select'], 'sum(cancel_order_num) order_num', 'sum(cancel_order_money) order_money', 'sum(cancel_goods_num) goods_num');
  404. $where['where'][] = ['>', 'cancel_order_num', 0];
  405. }
  406. //已退款单数
  407. if ($params['status'] == 3) {
  408. array_push($where['select'], 'sum(refund_order_num) order_num', 'sum(refund_order_money) order_money', 'sum(refund_goods_num) goods_num');
  409. $where['where'][] = ['>', 'refund_order_num', 0];
  410. }
  411. //全部
  412. if (!$params['status']) {
  413. array_push($where['select'], 'sum(pay_num) order_num', 'sum(pay_money) order_money', 'sum(pay_goods_num) goods_num');
  414. }
  415. $where['limit'] = 10;
  416. $where['group'] = 'date';
  417. $where['order'] = 'date desc';
  418. $list = UserStatistics::listPage($where, false);
  419. foreach ($list['list'] as $k => $v) {
  420. $list['list'][$k]['date'] = substr($v['date'], 0, 4) . '-' . substr($v['date'], 4, 2) . '-' . substr($v['date'], 6, 2);
  421. }
  422. $allWhere['where'] = $where['where'];
  423. $allData = UserStatistics::getOrderStatistics(
  424. $allWhere,
  425. ['sum(pay_num) pay_num', 'sum(pay_goods_num) pay_goods_num', 'count(user_id) user_num', 'sum(pay_money) pay_money']
  426. );
  427. $list['all_data'] = $allData[0];//总成交
  428. $date = date("Ymd", time());
  429. $nowWhere['where'] = [['=', 'mall_id', $this->mall_id], ['=', 'date', $date]];
  430. $nowData = UserStatistics::getOrderStatistics(
  431. $nowWhere,
  432. ['sum(pay_num) pay_num', 'sum(pay_goods_num) pay_goods_num', 'count(user_id) user_num', 'sum(pay_money) pay_money']
  433. );
  434. $list['now_data'] = $nowData[0];//今日实时成交
  435. return $this->success('操作成功', $list);
  436. }
  437. return $this->render('sale-statistics');
  438. }
  439. public function actionSaleStatistics() {
  440. if (\Yii::$app->request->isAjax) {
  441. $params = Yii::$app->request->get();
  442. $where = [];
  443. $where[]=['mall_id'=>$this->mall_id];
  444. $where[]=['status'=>StatusEnum::ENABLED];
  445. if ( !empty($params['date_start'])) {
  446. $where[] = ['>=', 'created_at', strtotime($params['date_start'].' 00:00:00')];
  447. }
  448. if (!empty($params['date_end'])) {
  449. $where[] = ['<=', 'created_at', strtotime($params['date_end'].' 23:59:59')];
  450. }
  451. $params['where'] = $where;
  452. $select = 'add_pay_orders as order_num,add_pay_nums as goods_num,add_pay_people_nums as user_num,total_pay_money as order_money,date';
  453. $params = array( 'where' => $where, 'select'=>$select,'order'=>'date desc', 'limit' => 20,);
  454. $list = CensusMallSingleDay::listPage($params,false);
  455. $params['select'] = 'sum(add_pay_orders) pay_num,sum(add_pay_nums) pay_goods_num,sum(add_pay_people_nums) user_num,sum(total_pay_money) pay_money';
  456. $result = CensusMallSingleDay::lists($params);
  457. $list['all_data'] = [ 'pay_num'=>0,'pay_goods_num'=>0,'user_num'=>0,'pay_money'=>0];
  458. if(!empty($result))$list['all_data'] = $result[0];//总成交
  459. $date = date("Y-m-d", time());
  460. $result = CensusMallSingleDay::getOne([['mall_id'=>$this->mall_id],['date'=>$date]],true);
  461. $list['now_data'] = [
  462. 'pay_num'=>0,'pay_goods_num'=>0,'user_num'=>0,'pay_money'=>0,
  463. ];
  464. if($result){
  465. $list['now_data'] = [
  466. 'pay_num'=>$result['add_pay_orders'],'pay_goods_num'=>$result['add_pay_nums'],
  467. 'user_num'=>$result['add_pay_people_nums'],'pay_money'=>$result['total_pay_money'],
  468. ];
  469. }
  470. return $this->success('操作成功', $list);
  471. }
  472. return $this->render('sale-statistics');
  473. }
  474. /**
  475. * 团队人数
  476. *
  477. * @return mixed
  478. */
  479. public function actionTeamSize()
  480. {
  481. if (Yii::$app->request->isAjax) {
  482. $params = Yii::$app->request->get();
  483. $service = new TeamService(['mall_id' => $this->mall_id]);
  484. return $this->success('操作成功', $service->getTeamSizePageList($params));
  485. }
  486. return $this->render($this->action->id);
  487. }
  488. /**
  489. * (个人)团队业绩
  490. *
  491. * @param integer $uid
  492. * @return mixed
  493. */
  494. public function actionTeamAchievement(int $uid)
  495. {
  496. if (Yii::$app->request->isAjax) {
  497. $params = Yii::$app->request->get();
  498. $service = new TeamService(['mall_id' => $this->mall_id]);
  499. return $this->success('操作成功', $service->getTeamAchievementPageList($uid, $params));
  500. }
  501. return $this->render($this->action->id);
  502. }
  503. public function actionTeamAchievementExport()
  504. {
  505. $data = Yii::$app->request->post('params');
  506. if (empty($data)) {
  507. return $this->error('参数错误');
  508. }
  509. $filename = '团队业绩数据-' . date('YmdHis') . '_' . rand(10000, 99999);
  510. $data['mall_id'] = $this->mall_id;
  511. $res = CsvExportHelper::exportDownLoadCenter($this->mall_id, $filename, DownloadEnum::TYPE_GROUP_DATA, TeamService::class, 'achievementExport', $data);
  512. if ($res === false) {
  513. return $this->error('加入导出任务失败' . CsvExportHelper::getStaticError());
  514. }
  515. return $this->success('添加导出任务成功,任务完成后请在下载中心进行下载!');
  516. }
  517. /**
  518. * 会员数据
  519. */
  520. public function actionUserData() {
  521. if (Yii::$app->request->isAjax) {
  522. $post = Yii::$app->request->get();
  523. $params['limit' ] = 10;
  524. $params['where'][] = ['=', 'mall_id', $this->mall_id];
  525. $params['where'][] = ['in', 'status', [StatusEnum::ENABLED,StatusEnum::DISABLED]];
  526. if (isset($post['level'])&&!empty($post['level']!=-1)) $params['where'][] = ['=', 'level', $post['level']];
  527. if (isset($post['keyword']) && !empty($post['keyword'])) {
  528. $params['where'][] = [
  529. 'or',
  530. ['like', 'nickname', $post['keyword']],
  531. ['=', 'mobile', $post['keyword']],
  532. ['=', 'id', $post['keyword']]
  533. ];
  534. }
  535. $params['order'] = 'id asc';
  536. $params['select'] = ['nickname', 'id', 'avatar_url', 'mobile', 'level',];
  537. $data = User::listPage($params, false);
  538. if ($data === false) return $this->error(User::getStaticError());
  539. if(!empty($data['list'])){
  540. $user_id_arr = array_column($data['list'],'id');
  541. $user_data = CensusMallUser::lists(['where'=> [['user_id'=>$user_id_arr]], 'index'=>'user_id']);
  542. foreach ($data['list'] as &$item){
  543. $item['pay_num'] = $item['pay_money'] = $item['finish_order_num'] = $item['finish_order_money'] = 0;
  544. if(isset($user_data[$item['id']])){
  545. $item['pay_num'] = $user_data[$item['id']]['add_orders'];
  546. $item['pay_money'] = $user_data[$item['id']]['add_order_money'];
  547. $item['finish_order_num'] = $user_data[$item['id']]['add_sale_orders'];
  548. $item['finish_order_money'] = $user_data[$item['id']]['add_sale_money'];
  549. }
  550. }
  551. }
  552. $levels = UserLevel::getListIndexByLevelColumn($this->mall_id,[StatusEnum::ENABLED,StatusEnum::DISABLED]);
  553. $data['levels'] = $levels;
  554. $this->success('操作成功', $data);
  555. }
  556. return $this->render('user-data');
  557. }
  558. /**
  559. * 导出
  560. */
  561. public function actionExport() {
  562. $type = Yii::$app->request->post('type');
  563. $data['mall_id'] = $this->mall_id;
  564. switch ($type) {
  565. case 'goods_rank':
  566. $filename = '商品购买力列表-' . date('YmdHis').'_'.rand(10000,99999);
  567. $res = CsvExportHelper::exportDownLoadCenter($this->mall_id,$filename,DownloadEnum::TYPE_STATISTICS,GoodsStatistics::class,'exportRankHandle',$data);
  568. break;
  569. case 'user_rank':
  570. $filename = '用户购买力列表-' . date('YmdHis').'_'.rand(10000,99999);
  571. $res = CsvExportHelper::exportDownLoadCenter($this->mall_id,$filename,DownloadEnum::TYPE_STATISTICS,UserStatistics::class,'exportRankHandle',$data);
  572. break;
  573. case 'sale-statistics':
  574. $filename = '销售数据列表-' . date('YmdHis').'_'.rand(10000,99999);
  575. $res = CsvExportHelper::exportDownLoadCenter($this->mall_id,$filename,DownloadEnum::TYPE_STATISTICS,UserStatistics::class,'exportSaleStatisticsHandle',$data);
  576. break;
  577. case 'team-size':
  578. $filename = '渠道人数列表-' . date('YmdHis').'_'.rand(10000,99999);
  579. $data = Yii::$app->request->post('params');
  580. $data['mall_id'] = $this->mall_id;
  581. $res = CsvExportHelper::exportDownLoadCenter($this->mall_id,$filename,DownloadEnum::TYPE_MEMBER,User::class,'exportTeamSizeHandle',$data);
  582. break;
  583. default:
  584. # code...
  585. break;
  586. }
  587. if ($res === false) return $this->error('加入导出任务失败'.CsvExportHelper::getStaticError());
  588. return $this->success('添加导出任务成功,任务完成后请在下载中心进行下载!');
  589. }
  590. public function actionCarUserData()
  591. {
  592. if (!\Yii::$app->request->isAjax) {
  593. return $this->render('/census/user-data');
  594. }
  595. $mall_id = $this->mall_id;
  596. $user_list = [];
  597. $redis = Yii::$app->redis;
  598. //获取等级分布开始
  599. $level = [];//会员等级分布
  600. $active_members = [];//会员活跃数
  601. $order = [];//复购数据
  602. $deal_members = [];//成交客户
  603. $cumulative_members = [];//累计会员数
  604. $redis_level_key = RedisKeyEnum::suffix(RedisKeyEnum::CENSUS_MALL_USER_LEVEL, '', true) . ':' . $mall_id;
  605. $redis_single_date_key = RedisKeyEnum::suffix(RedisKeyEnum::CENSUS_MALL_SINGLE_DATE, '', true) . ':' . $mall_id;
  606. $redis_census_mall_key = RedisKeyEnum::suffix(RedisKeyEnum::CENSUS_MALL, '', true) . ':' . $mall_id;
  607. $result = $redis->hgetall($redis_level_key);
  608. if ($result) {
  609. $levels = UserLevel::getUserLevelArr($mall_id);
  610. foreach ($result as $key => $value) {
  611. if ($key % 2 == 0) {
  612. $level_key[] = $value;
  613. } else {
  614. $level_value[] = $value;
  615. }
  616. }
  617. $total_level_num = array_sum($level_value);
  618. $proportion_num = 100;
  619. $level_count = count($level_key);
  620. foreach ($level_key as $k => $v) {
  621. $level_exp = [];
  622. $level_exp = explode('_', $v);
  623. $now_proportion_num = floor($level_value[$k] / $total_level_num * 100);
  624. if ($k == $level_count - 1) {
  625. $now_proportion_num = $proportion_num;
  626. }
  627. if ($now_proportion_num == 0) {
  628. $now_proportion_num = ceil($level_value[$k] / $total_level_num * 100);
  629. }
  630. $proportion_num -= $now_proportion_num;
  631. if (isset($levels[$level_exp[1]])) {
  632. $level[$k]['level_name'] = $levels[$level_exp[1]];
  633. $level[$k]['num'] = $level_value[$k];
  634. $level[$k]['proportion'] = $now_proportion_num;
  635. } else {
  636. $level[$k]['level_name'] = '普通用户';
  637. $level[$k]['num'] = $level_value[$k];
  638. $level[$k]['proportion'] = $now_proportion_num;
  639. }
  640. }
  641. }
  642. //获取等级分布结束
  643. //获取活跃会员开始
  644. $day = date('Y-m-d', time());
  645. for ($i = 0; $i < 5; $i++) {
  646. $now_day = $day;
  647. if ($i > 0) {
  648. $now_day = date("Y-m-d", strtotime("-" . $i . " day", strtotime($day)));
  649. }
  650. $redis_key = $redis_single_date_key . ':' . $now_day;
  651. $active_members[$i]['num'] = $redis->hget($redis_key, 'total_actives') ?? 0;
  652. $active_members[$i]['day'] = date('m-d', strtotime($now_day));
  653. $user_list[$i]['num'] = $redis->hget($redis_key, 'total_users') ?? 0;
  654. $user_list[$i]['day'] = date('m-d', strtotime($now_day));
  655. }
  656. if($active_members){
  657. $active_members = array_reverse($active_members);
  658. }
  659. if($user_list){
  660. $user_list = array_reverse($user_list);
  661. }
  662. //获取活跃会员结束
  663. //复购情况开始
  664. $order['repurchase_people'] = $redis->hget($redis_census_mall_key, 'repurchase_people') ?? 0;//复购会员数
  665. $order['total_pay_people'] = $redis->hget($redis_census_mall_key, 'total_pay_people') ?? 0;//支付人数
  666. $total_views = $redis->hget($redis_census_mall_key, 'total_visitors') ?? 0;//
  667. $total_orders = $redis->hget($redis_census_mall_key, 'number_of_orders') ?? 0;//
  668. $total_pay_orders = $redis->hget($redis_census_mall_key, 'total_pay_people') ?? 0;//
  669. $order['order_proportion'] = 0;
  670. $order['pay_order_proportion'] = 0;
  671. if ($total_views > 0) {
  672. if ($total_orders > 0) {
  673. $order['order_proportion'] = (bcdiv($total_orders , $total_views,2)*100).'%';//
  674. }
  675. if ($total_pay_orders > 0) {
  676. $order['pay_order_proportion'] =(bcdiv($total_pay_orders , $total_views,2)*100).'%';
  677. }
  678. }
  679. //复购情况结束
  680. //成交会员开始
  681. $deal_members['new_customers_pay_peoples'] = $redis->hget($redis_census_mall_key, 'new_customers_pay_peoples') ?? 0;//新客户成交人数
  682. $deal_members['new_customers_pay_money'] = $redis->hget($redis_census_mall_key, 'new_customers_pay_money') ?? 0;//新客户成交金额
  683. $deal_members['regular_customers_pay_peoples'] = $redis->hget($redis_census_mall_key, 'regular_customers_pay_peoples') ?? 0;//老客户成交人数
  684. $deal_members['regular_customers_pay_money'] = $redis->hget($redis_census_mall_key, 'regular_customers_pay_money') ?? 0;//老客户成交金额
  685. $total_pay_people = $deal_members['new_customers_pay_peoples'] + $deal_members['regular_customers_pay_peoples'];
  686. $total_pay_money = bcadd($deal_members['new_customers_pay_money'], $deal_members['regular_customers_pay_money'], 2);
  687. $deal_members['new_customers_proportion'] = ceil($deal_members['new_customers_pay_peoples'] / $total_pay_people * 100);
  688. $deal_members['regular_customers_proportion'] = 100 - $deal_members['new_customers_proportion'];
  689. $deal_members['new_customers_pay_money_proportion'] = ceil($deal_members['new_customers_pay_money'] / $total_pay_money * 100);
  690. $deal_members['regular_customers_pay_money_proportion'] = 100 - $deal_members['new_customers_pay_money_proportion'];
  691. //成交会员结束
  692. //累计会员开始
  693. $cumulative_members['total_users'] = $redis->hget($redis_census_mall_key, 'total_users') ?? 0;//新客户成交人数
  694. $cumulative_members['new_user'] = $user_list;//新客户成交人数
  695. //累计会员结束
  696. return $this->success('获取成功', compact('cumulative_members', 'level', 'active_members', 'order', 'deal_members'));
  697. }
  698. public function actionCarUserTradData()
  699. {
  700. if (!\Yii::$app->request->isAjax) {
  701. return $this->render('/census/transaction-data');
  702. }
  703. $mall_id = $this->mall_id;
  704. $redis = Yii::$app->redis;
  705. $from = [];
  706. $trad_trend = [];
  707. $trad_map = [];
  708. $cart = [];
  709. $rank = [];
  710. $redis_census_mall_key = RedisKeyEnum::suffix(RedisKeyEnum::CENSUS_MALL, '', true) . ':' . $mall_id;
  711. $redis_census_map_key = RedisKeyEnum::suffix(RedisKeyEnum::CENSUS_MALL_REGION, '', true) . ':' . $mall_id;
  712. $redis_goods_member_key = RedisKeyEnum::suffix(RedisKeyEnum::CENSUS_MALL_GOODS_CARD_NUMBERS, '', true) . ':' . $mall_id;
  713. $redis_goods_money_key = RedisKeyEnum::suffix(RedisKeyEnum::CENSUS_MALL_GOODS_PAY_MONEY, '', true) . ':' . $mall_id;
  714. $total_num = $redis->hget($redis_census_mall_key, 'total_pay_money') ?? 0;
  715. //访客下单支付开始
  716. $from['total_visitors'] = $redis->hget($redis_census_mall_key, 'total_visitors') ?? 0;//访客
  717. $from['number_of_orders'] = $redis->hget($redis_census_mall_key, 'number_of_orders') ?? 0;//下单人数
  718. $from['total_order_money'] = $redis->hget($redis_census_mall_key, 'total_order_money') ?? 0;//下单金额
  719. $from['total_pay_money'] = $redis->hget($redis_census_mall_key, 'total_pay_money') ?? 0;//支付金额
  720. $from['total_pay_people'] = $redis->hget($redis_census_mall_key, 'total_pay_people') ?? 0;//支付人数
  721. $from['order_proportion'] = 0;//下单转化率
  722. $from['pay_proportion'] = 0;//支付转化率
  723. $from['unit_price'] = 0;//客单价
  724. if ($from['total_pay_people'] > 0 && $from['total_pay_money'] > 0) {
  725. $from['unit_price'] = bcdiv($from['total_pay_money'], $from['total_pay_people'], 2);
  726. }
  727. if ($from['total_visitors'] > 0) {
  728. if ($from['number_of_orders'] > 0) {
  729. $from['order_proportion'] = bcdiv($from['number_of_orders'] , $from['total_visitors'],2)*100;//
  730. }
  731. if ($from['total_pay_people'] > 0) {
  732. $from['pay_proportion'] =bcdiv($from['total_pay_people'] , $from['total_visitors'],2)*100;
  733. }
  734. }
  735. //访客下单支付结束
  736. //实时成交趋势
  737. $date = date('Y-m-d', time());
  738. // $date = '2022-04-12';
  739. $redis_key = RedisKeyEnum::suffix(RedisKeyEnum::CENSUS_MALL_SINGLE_HOUR . ':' . $mall_id . ':' . $date, '', true);
  740. $result = $redis->hgetall($redis_key);
  741. if ($result) {
  742. foreach ($result as $key => $value) {
  743. if ($key % 2 == 0) {
  744. $trad_trend_key[] = $value;
  745. } else {
  746. $trad_trend_value[] = $value;
  747. }
  748. }
  749. foreach ($trad_trend_key as $k => $v) {
  750. $hour = explode('_', $v);
  751. $trad_trend[$k]['hour'] = $hour[1];
  752. $trad_trend[$k]['num'] = $trad_trend_value[$k];
  753. }
  754. }
  755. // 实时成交趋势
  756. //加购情况
  757. $cart_list = $redis->zrevrange($redis_goods_member_key, 0, 9, 'WITHSCORES');
  758. if ($cart_list) {
  759. foreach ($cart_list as $ke => $valu) {
  760. if ($ke % 2 == 0) {
  761. $cart_trend_key[] = $valu;
  762. } else {
  763. $cart_trend_value[] = $valu;
  764. }
  765. }
  766. foreach ($cart_trend_key as $item => $val) {
  767. $goods_id = explode(':', $val);
  768. $name = Goods::getOne([['id' => $goods_id[1]]], true, [], '', 'goods_name,cover_pic');
  769. $cart[$item]['goods_name'] = $name['goods_name'];
  770. $cart[$item]['cover_pic'] = $name['cover_pic'];
  771. $cart[$item]['num'] = $cart_trend_value[$item];
  772. }
  773. }
  774. //加购情况
  775. //销售排行榜
  776. $rank_list = $redis->zrevrange($redis_goods_money_key, 0, 9, 'WITHSCORES');
  777. if ($rank_list) {
  778. foreach ($rank_list as $index => $vv) {
  779. if ($index % 2 == 0) {
  780. $rank_trend_key[] = $vv;
  781. } else {
  782. $rank_trend_value[] = $vv;
  783. }
  784. }
  785. foreach ($rank_trend_key as $i => $va) {
  786. $goods_id = explode(':', $va);
  787. $name = Goods::getOne([['id' => $goods_id[1]]], true, [], '', 'goods_name,cover_pic');
  788. $rank[$i]['goods_name'] = $name['goods_name'];
  789. $rank[$i]['cover_pic'] = $name['cover_pic'];
  790. $rank[$i]['num'] = round($rank_trend_value[$i], 2);
  791. }
  792. }
  793. //销售排行榜
  794. //交易地图热点
  795. $map_list = $redis->hgetall($redis_census_map_key);
  796. if ($map_list) {
  797. foreach ($map_list as $kk => $vva) {
  798. if ($kk % 2 == 0) {
  799. $map_trend_key[] = $vva;
  800. } else {
  801. $map_trend_value[] = $vva;
  802. }
  803. }
  804. $n = 0;
  805. foreach ($map_trend_key as $now_key => $now_val) {
  806. $ex_key = explode('id_', $now_val);
  807. if ($ex_key[0] == 'total_orders_province_') {
  808. $trad_map[$n]['province_id'] = $ex_key[1];
  809. $trad_map[$n]['order_num'] = $map_trend_value[$now_key];
  810. $n++;
  811. }
  812. }
  813. $province_ids = array_column($trad_map, 'province_id');
  814. $provinces = Region::find()
  815. ->select('id,name,short_title,areacode,initial')
  816. ->where(['id' => $province_ids, 'level' => 1])
  817. ->asArray()
  818. ->indexBy('id')
  819. ->all();
  820. foreach ($trad_map as &$items) {
  821. $province = $provinces[$items['province_id']] ?? [];
  822. $items['province_name'] = $province['name'] ?? '';
  823. $items['province_short_title'] = $province['short_title'] ?? '';
  824. }
  825. }
  826. //交易地图热点
  827. $user_ids = Order::find()->andWhere(['mall_id'=>$mall_id,'pay_status'=>1,'store_id'=>0,'mch_id'=>0])
  828. ->orderBy('id desc')->groupBy('user_id')->select('user_id')
  829. ->limit(20)->column();
  830. $scroll = [];
  831. if ($user_ids) {
  832. $user_name = User::lists(['where' => [['in','id',$user_ids]], 'select' => 'nickname,id','index'=>'id']);
  833. if($user_name){
  834. foreach ($user_ids as $user_id){
  835. if(isset($user_name[$user_id])){
  836. $scroll[] = $user_name[$user_id]['nickname'].'支付了订单';
  837. }
  838. }
  839. }
  840. }
  841. return $this->success('获取成功', compact('from', 'trad_trend', 'trad_map', 'cart', 'rank', 'total_num','scroll'));
  842. }
  843. public function actionCarAnalysis()
  844. {
  845. if (!\Yii::$app->request->isAjax) {
  846. return $this->render('/census/analysis');
  847. }
  848. $type = Yii::$app->request->get('type');
  849. $mall_id = $this->mall_id;
  850. $redis = \Yii::$app->redis;
  851. if ($type == 1) {
  852. $redis_key = RedisKeyEnum::suffix(RedisKeyEnum::CENSUS_MALL_RF_ANALYSIS, '', true) . ':' . $mall_id;
  853. $total_pay_money = 'f_total_pay_money';
  854. $users = 'f_users';
  855. } else {
  856. $redis_key = RedisKeyEnum::suffix(RedisKeyEnum::CENSUS_MALL_RM_ANALYSIS, '', true) . ':' . $mall_id;
  857. $total_pay_money = 'm_total_pay_money';
  858. $users = 'm_users';
  859. }
  860. $result = $redis->get($redis_key);
  861. if ($result) {
  862. $result = \Qiniu\json_decode($result, true);
  863. foreach ($result as $k => &$v) {
  864. $v['unit_price1'] = 0;
  865. $v['unit_price2'] = 0;
  866. $v['unit_price3'] = 0;
  867. $v['unit_price4'] = 0;
  868. $v['unit_price5'] = 0;
  869. if ($v[$total_pay_money . '1'] > 0 && $v[$users . '1'] > 0) {
  870. $v['unit_price1'] = bcdiv($v[$total_pay_money . '1'], $v[$users . '1'], 2);
  871. }
  872. if ($v[$total_pay_money . '2'] > 0 && $v[$users . '2'] > 0) {
  873. $v['unit_price2'] = bcdiv($v[$total_pay_money . '2'], $v[$users . '2'], 2);
  874. }
  875. if ($v[$total_pay_money . '3'] > 0 && $v[$users . '3'] > 0) {
  876. $v['unit_price3'] = bcdiv($v[$total_pay_money . '3'], $v[$users . '3'], 2);
  877. }
  878. if ($v[$total_pay_money . '4'] > 0 && $v[$users . '4'] > 0) {
  879. $v['unit_price4'] = bcdiv($v[$total_pay_money . '4'], $v[$users . '4'], 2);
  880. }
  881. if ($v[$total_pay_money . '5'] > 0 && $v[$users . '5'] > 0) {
  882. $v['unit_price5'] = bcdiv($v[$total_pay_money . '5'], $v[$users . '5'], 2);
  883. }
  884. }
  885. }
  886. return $this->success('获取成功', $result);
  887. }
  888. /**
  889. * @notes:老用户订单数据更新
  890. * @author: lun
  891. * @Time: 2022/11/8 14:09
  892. */
  893. public function actionUpdateFinishOrder()
  894. {
  895. if (Yii::$app->request->isPost) {
  896. $redis = Yii::$app->redis;
  897. $cacheKey = RedisKeyEnum::suffix(\common\models\statistics\UserTeamStatistics::COUNT_FINISH_ORDER_KEY, 'mall_id_' . $this->mall_id);
  898. $checkCount = $redis->get($cacheKey);
  899. if ($checkCount && $checkCount == 1) return $this->error('数据正在更新或已更新完成');
  900. Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_TASK, RabbitMqEnum::TASK_QUEUE, ['mall_id' => $this->mall_id], UserTeamStatisticsLogic::class, 'countOldUserTeamAchievement');
  901. return $this->success('数据已进行异步更新,请耐心等候');
  902. }
  903. }
  904. /**
  905. * @return string|void
  906. */
  907. public function actionAllPayTypeRefund()
  908. {
  909. $service = new StatisticsService(['mall_id' => $this->mall_id]);
  910. if (!\Yii::$app->request->isAjax) {
  911. $thisMonth = array_values(DateHelper::thisMonth());
  912. array_walk($thisMonth, function (&$val) {
  913. $val = date('Y-m-d', $val);
  914. });
  915. return $this->render(
  916. $this->action->id,
  917. [
  918. 'pay_type_option' => json_encode($service->getPayTypeOption()),
  919. 'pay_identifier_option' => json_encode($service->getPayIdentifierOption()),
  920. 'export_field' => json_encode($service->getAllPayTypeRefundExportField()),
  921. 'this_month' => json_encode($thisMonth), // 默认查询本月的数据
  922. ]
  923. );
  924. }
  925. $this->success('success', $service->allPayTypeRefund($this->request->get()));
  926. }
  927. /**
  928. * @return string|void
  929. */
  930. public function actionAllPayTypeRefundDetails()
  931. {
  932. $service = new StatisticsService(['mall_id' => $this->mall_id]);
  933. if (!\Yii::$app->request->isAjax) {
  934. $thisMonth = array_values(DateHelper::thisMonth());
  935. array_walk($thisMonth, function (&$val) {
  936. $val = date('Y-m-d H:i:s', $val);
  937. });
  938. return $this->render(
  939. $this->action->id,
  940. [
  941. 'export_field' => json_encode($service->getAllPayTypeRefundDetailsExportField()),
  942. 'this_month' => json_encode($thisMonth), // 默认查询本月的数据
  943. ]
  944. );
  945. }
  946. $get = $this->request->get();
  947. $valid = Yii::$app->services->validate->validate($get, [
  948. [['id'], 'required'],
  949. [['id', 'user_keyword'], 'number', 'min' => 0],
  950. [['daterange'], 'safe'],
  951. ]);
  952. if ($valid === false) {
  953. $this->error(Yii::$app->services->validate->getErrorMessage());
  954. return;
  955. }
  956. $this->success('success', $service->allPayTypeRefundDetails($get));
  957. }
  958. /**
  959. * @return mixed|null
  960. * @throws \Random\RandomException
  961. */
  962. public function actionAllPayTypeRefundExport()
  963. {
  964. $data = Yii::$app->request->post();
  965. if (empty($data['daterange'])) {
  966. $filename = '支付通道退款统计数据_' . date('YmdHis') . '_' . random_int(10000, 99999);
  967. } else {
  968. $filename = sprintf('支付通道退款统计数据_%s至%s_%d', $data['daterange'][0], $data['daterange'][1], random_int(10000, 99999));
  969. }
  970. $data['mall_id'] = $this->mall_id;
  971. $res = CsvExportHelper::exportDownLoadCenter($this->mall_id, $filename, DownloadEnum::TYPE_PAY_TYPE_REFUND_STATISTICS, StatisticsService::class, 'allPayTypeRefundExport', $data);
  972. if ($res === false) return $this->error('加入导出任务失败' . CsvExportHelper::getStaticError());
  973. return $this->success('添加导出任务成功,任务完成后请在下载中心进行下载!');
  974. }
  975. /**
  976. * @return mixed|null
  977. * @throws \Random\RandomException
  978. */
  979. public function actionAllPayTypeRefundDetailsExport()
  980. {
  981. $data = Yii::$app->request->post();
  982. if (empty($data['daterange'])) {
  983. $filename = '支付通道退款统计明细数据_' . date('YmdHis') . '_' . random_int(10000, 99999);
  984. } else {
  985. $filename = sprintf('支付通道退款统计明细数据_%s至%s_%d', $data['daterange'][0], $data['daterange'][1], random_int(10000, 99999));
  986. }
  987. $data['mall_id'] = $this->mall_id;
  988. $res = CsvExportHelper::exportDownLoadCenter($this->mall_id, $filename, DownloadEnum::TYPE_PAY_TYPE_REFUND_STATISTICS_DETAILS, StatisticsService::class, 'allPayTypeRefundDetailsExport', $data);
  989. if ($res === false) return $this->error('加入导出任务失败' . CsvExportHelper::getStaticError());
  990. return $this->success('添加导出任务成功,任务完成后请在下载中心进行下载!');
  991. }
  992. /**
  993. * 订单详情
  994. */
  995. public function actionOrderDetail()
  996. {
  997. $order_id = $this->request->get('order_id');
  998. if (!is_numeric($order_id)) return $this->error('参数错误');
  999. $order = Order::find()->where(['id' => $order_id, 'status' => StatusEnum::ENABLED])->with(['detail'])->asArray()->all();
  1000. if (!$order) return $this->error('订单不存在');
  1001. $return_data = [];
  1002. foreach ($order as &$item) {
  1003. $temp = [];
  1004. foreach ($item['detail'] as &$detail) {
  1005. $temp[$detail['goods_id']][] = $detail;
  1006. }
  1007. foreach ($temp as $goods_detail) {
  1008. $item['detail'] = [];
  1009. $item['detail'] = $goods_detail;
  1010. $return_data[] = $item;
  1011. }
  1012. }
  1013. return $this->success('success', $return_data);
  1014. }
  1015. }