Center.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types = 1);
  12. namespace app\store\controller\statistics;
  13. use app\common\library\helper;
  14. use app\common\model\GoodsSalesRank;
  15. use app\store\controller\Controller;
  16. use app\store\model\ChannelSaleStatistics;
  17. use app\store\model\ChannelSaleVolumeTj;
  18. use app\store\model\GoodsVisitStatistics;
  19. use app\store\model\GoodsSaleStatistics;
  20. use app\store\model\RefundGoodsStatistics;
  21. use app\store\model\ShopsDailySalesSt;
  22. use app\common\service\Export as ExportService;
  23. use app\store\model\ShopsMonthlyBonusSt;
  24. use app\store\model\StoreDailySalesSt;
  25. use think\facade\Validate;
  26. /**
  27. * 数据概况
  28. * Class Data
  29. * @package app\store\controller\statistics
  30. */
  31. class Center extends Controller
  32. {
  33. /**
  34. * 数据统计主页
  35. * @return array
  36. * @throws \think\db\exception\DataNotFoundException
  37. * @throws \think\db\exception\DbException
  38. * @throws \think\db\exception\ModelNotFoundException
  39. */
  40. public function data()
  41. {
  42. $betweenTime = $this->request->param('betweenTime');
  43. if ($betweenTime){
  44. $times = between_time($betweenTime);
  45. }else{
  46. $times['end_time'] = strtotime(date('Y-m-01 00:00:00')) - 1 ;//上月的最后一秒
  47. $times['start_time'] =strtotime(date('Y-m-01 00:00:00',strtotime('-1 month')));
  48. }
  49. $param = $this->request->param();
  50. // 获取数据
  51. /* $from = 1645545600;
  52. $to = 1645631940;*/
  53. $m = new ShopsDailySalesSt();
  54. $list = $m->listSt($times['start_time'],$times['end_time'],$param);
  55. return $this->renderSuccess(compact('list'));
  56. }
  57. public function exportData(){
  58. $param = $this->request->param('queryParam');
  59. $betweenTime = $param['betweenTime']??null;
  60. $type = intval($this->request->param('type',1));
  61. if ($betweenTime){
  62. $times = between_time($betweenTime);
  63. }else{
  64. $times['end_time'] = strtotime(date('Y-m-01 00:00:00')) - 1 ;//上月的最后一秒
  65. $times['start_time'] =strtotime(date('Y-m-01 00:00:00',strtotime('-1 month')));
  66. }
  67. if ($type == 1){
  68. $model = new ShopsDailySalesSt();
  69. $data = $model->listsExport($times['start_time'],$times['end_time'],$param);
  70. }elseif($type == 3){
  71. //门店业绩排行导出
  72. $model = new ShopsDailySalesSt();
  73. $data = $model->listsRankExport($times['start_time'],$times['end_time']);
  74. }else{
  75. $from = date('Ym',$times['start_time']);
  76. $to = date('Ym',$times['end_time']);
  77. $model = new ShopsMonthlyBonusSt();
  78. $data = $model->listsExport($from,$to,$param);
  79. }
  80. $res = ExportService::export($data['data'],$data['header'],$data['filename'],'列表','Xls');
  81. return $this->renderSuccess($res,'导出成功');
  82. }
  83. /**
  84. * 奖励金数据统计
  85. * @return array
  86. */
  87. public function bonusData(){
  88. $betweenTime = $this->request->param('betweenTime');
  89. if ($betweenTime){
  90. $times = between_time($betweenTime);
  91. }else{
  92. $times['end_time'] = strtotime(date('Y-m-01 00:00:00')) - 1 ;//上月的最后一秒
  93. $times['start_time'] =strtotime(date('Y-m-01 00:00:00',strtotime('-1 month')));
  94. }
  95. $param = $this->request->param();
  96. $from = date('Ym',$times['start_time']);
  97. $to = date('Ym',$times['end_time']);
  98. $m = new ShopsMonthlyBonusSt();
  99. $list = $m->listSt($from,$to,$param);
  100. return $this->renderSuccess(compact('list'));
  101. }
  102. /** 门店业绩排名
  103. * @return array
  104. * @throws \think\db\exception\DataNotFoundException
  105. * @throws \think\db\exception\DbException
  106. * @throws \think\db\exception\ModelNotFoundException
  107. */
  108. public function dataRank()
  109. {
  110. $betweenTime = $this->request->param('betweenTime');
  111. $page = $this->request->param('page',1);
  112. if ($betweenTime){
  113. $times = between_time($betweenTime);
  114. }else{
  115. $times['end_time'] = strtotime(date('Y-m-01 00:00:00')) - 1 ;//上月的最后一秒
  116. $times['start_time'] =strtotime(date('Y-m-01 00:00:00',strtotime('-1 month')));
  117. }
  118. // 获取数据
  119. $m = new ShopsDailySalesSt();
  120. $list = $m->listStRank($times['start_time'],$times['end_time'],$page);
  121. return $this->renderSuccess(compact('list'));
  122. }
  123. public function getthemonth($date)
  124. {
  125. $firstday = date('Ym01', strtotime($date));
  126. $lastday = date('Ymd', strtotime("$firstday +1 month -1 day"));
  127. return array($firstday, $lastday);
  128. }
  129. /**
  130. * 交易数据-单月销售数据看板
  131. */
  132. public function saleVolumeBoard(){
  133. $betweenTime = $this->request->param('betweenTime',null);
  134. if (!$betweenTime){
  135. $betweenTime = date('Y-m');
  136. }
  137. $validate = Validate::rule('date', 'date');
  138. $data = [
  139. 'date' => $betweenTime,
  140. ];
  141. if (!$validate->check($data)) {
  142. return $this->renderError($validate->getError());
  143. }
  144. $times = $this->getthemonth($betweenTime);
  145. $from = $times[0];
  146. if (intval($from) < 20211001){
  147. return $this->renderError('不支持此范围查询');
  148. }
  149. $to = $times[1];
  150. $m = new StoreDailySalesSt();
  151. $list = $m->listAMonthSt($from,$to);
  152. $list = $list?$list->toArray():[];
  153. $_31 = [1=>31,2=>29,3=>31,4=>30,5=>31,6=>30,7=>31,8=>31,9=>30,10=>31,11=>30,12=>31];
  154. $lists = [];
  155. for ($i=1;$i<=$_31[intval(substr($betweenTime,5,2))];$i++){
  156. $lists[$i]['day'] = $i;
  157. $lists[$i]['sale_volume'] = '0.00';
  158. $lists[$i]['order_count'] = 0;
  159. foreach ($list as $item){
  160. if (intval($item['st_day']) == $i){
  161. $lists[$i]['sale_volume'] = $item['sale_volume'];
  162. $lists[$i]['order_count'] = $item['order_count'];
  163. }
  164. }
  165. }
  166. $sale_volumes = array_column($lists,'sale_volume');
  167. $order_counts = array_column($lists,'order_count');
  168. $days = array_column($lists,'day');
  169. array_walk($days,function (&$i){
  170. $i = $i.'日';
  171. });
  172. if ($this->request->isPost()) { // 导出数据
  173. $data['header'] = ['时间', '销售额(订单金额)', '成交订单数'];
  174. $data['filename'] = '销售额与订单数趋势对比导出';
  175. $data['data'] = [];
  176. foreach ($days as $k=>$day){
  177. $new_list['ref_date'] = $day;
  178. $new_list['sale_volumes'] = $sale_volumes[$k];
  179. $new_list['order_counts'] = $order_counts[$k];
  180. $data['data'][] = $new_list;
  181. }
  182. if (empty($data['data'])) {
  183. return $this->renderError('暂无数据');
  184. }
  185. $res = ExportService::export($data['data'],$data['header'],$data['filename'],'列表','Xls');
  186. return $this->renderSuccess($res,'导出成功');
  187. }
  188. return $this->renderSuccess(compact('sale_volumes','order_counts','days'));
  189. }
  190. /**
  191. * 交易数据-两月销售数据对比
  192. */
  193. public function saleBoardCompM(){
  194. $betweenTime = $this->request->param('betweenTime',null);
  195. if ($betweenTime){
  196. $validate = Validate::rule('date', 'date');
  197. $data = [
  198. 'date' => $betweenTime,
  199. ];
  200. if (!$validate->check($data)) {
  201. return $this->renderError($validate->getError());
  202. }
  203. $temps = strtotime($betweenTime);
  204. $times['end_time'] = strtotime(date('Y-m-01 00:00:00',strtotime('+1 month',$temps))) - 1;
  205. $times['start_time'] = strtotime('-1 month',$temps);
  206. }else{
  207. $times['end_time'] = strtotime(date('Y-m-01 00:00:00',strtotime('+1 month',time()))) - 1 ;//本月的最后一秒
  208. $times['start_time'] = mktime(0,0,0,intval(date('m')),1,intval(date('Y'))) - 1;//上月的最后一秒
  209. }
  210. $from = intval(date('Ym01',$times['start_time']));
  211. $to = intval(date('Ymd',$times['end_time']));
  212. $m = new StoreDailySalesSt();
  213. $list = $m->listAMonthSt($from,$to);
  214. $_31 = [1=>31,2=>29,3=>31,4=>30,5=>31,6=>30,7=>31,8=>31,9=>30,10=>31,11=>30,12=>31];
  215. $m1 = intval(date('m',$times['start_time']));
  216. $m2 = intval(date('m',$times['end_time']));
  217. //x轴坐标个数
  218. $days = $_31[$m1]>$_31[$m2]?$_31[$m1]:$_31[$m2];
  219. //$json = '[{"day":1,"value1":111,"value2":222},{"day":2,"value1":333,"value2":444}]';
  220. $lists = [];
  221. for ($i=0;$i<$days;$i++){
  222. $day = $i + 1;
  223. $lists[$i]['day'] = $day;
  224. $lists[$i]['value1'] = '0.00';//上月
  225. $lists[$i]['value2'] = '0.00';//本月
  226. foreach ($list as $item){
  227. if($item['st_day'] == $day){
  228. if (intval($item['int_month']) == $m1){
  229. $lists[$i]['value1'] = $item['sale_volume'];
  230. }
  231. if (intval($item['int_month']) == $m2){
  232. $lists[$i]['value2'] = $item['sale_volume'];
  233. }
  234. }
  235. }
  236. }
  237. $prevMonth= array_column($lists,'value1');
  238. $currentMonth = array_column($lists,'value2');
  239. $days = array_column($lists,'day');
  240. array_walk($days,function (&$i){
  241. $i = $i.'日';
  242. });
  243. if ($this->request->isPost()) { // 导出数据
  244. $data['header'] = ['时间', '上月(订单金额)', '本月(订单金额)'];
  245. $data['filename'] = '销售额趋势月度对比导出';
  246. $data['data'] = [];
  247. foreach ($days as $k=>$day){
  248. $new_list['ref_date'] = $day;
  249. $new_list['prev_month'] = $prevMonth[$k];
  250. $new_list['current_month'] = $currentMonth[$k];
  251. $data['data'][] = $new_list;
  252. }
  253. if (empty($data['data'])) {
  254. return $this->renderError('暂无数据');
  255. }
  256. $res = ExportService::export($data['data'],$data['header'],$data['filename'],'列表','Xls');
  257. return $this->renderSuccess($res,'导出成功');
  258. }
  259. return $this->renderSuccess(compact('currentMonth','prevMonth','days'));
  260. }
  261. /**
  262. * 交易数据-两年销售数据对比
  263. */
  264. public function saleBoardCompY(){
  265. $year = intval($this->request->param('betweenTime',null));
  266. if ($year){
  267. $times['end_time'] = mktime(23,59,59,12,31,$year);
  268. $times['start_time'] = mktime(0,0,0,1,1,$year-1);
  269. }else{
  270. $year = intval(date('Y'));
  271. $times['end_time'] = mktime(23,59,59,12,31,$year);
  272. $times['start_time'] = mktime(0,0,0,1,1,$year - 1);
  273. }
  274. $from = intval(date('Ymd',$times['start_time']));
  275. $to = intval(date('Ymd',$times['end_time']));
  276. $y1 = date('Y',$times['start_time']);
  277. $y2 = date('Y',$times['end_time']);
  278. $m = new StoreDailySalesSt();
  279. $list = $m->listTwoMonthSt($from,$to);
  280. //需要组装成前端需要的数据结构
  281. $lists = [['month'=>1],['month'=>2],['month'=>3],['month'=>4],['month'=>5],['month'=>6],['month'=>7],['month'=>8],['month'=>9],['month'=>10],['month'=>11],['month'=>12]];
  282. foreach ($lists as &$item){
  283. $item['value1'] = '0.00';//上月
  284. $item['value2'] = '0.00';//本月
  285. foreach ($list as $val){
  286. if (intval($val['int_month']) == $item['month']){
  287. if ($val['st_year'] == $y1){
  288. $item['value1'] = $val['sale_volume'];
  289. }
  290. if ($val['st_year'] == $y2){
  291. $item['value2'] = $val['sale_volume'];
  292. }
  293. }
  294. }
  295. }
  296. $prevYear = array_column($lists,'value1');
  297. $currentYear = array_column($lists,'value2');
  298. $months = array_column($lists,'month');
  299. array_walk($months,function (&$i){
  300. $i = $i.'月';
  301. });
  302. if ($this->request->isPost()) { // 导出数据
  303. $data['header'] = ['时间', '去年销售额', '今年销售额'];
  304. $data['filename'] = '销售额趋势年度对比导出';
  305. $data['data'] = [];
  306. foreach ($months as $k=>$month){
  307. $new_list['ref_date'] = $month;
  308. $new_list['prev_year'] = $prevYear[$k];
  309. $new_list['current_year'] = $currentYear[$k];
  310. $data['data'][] = $new_list;
  311. }
  312. if (empty($data['data'])) {
  313. return $this->renderError('暂无数据');
  314. }
  315. $res = ExportService::export($data['data'],$data['header'],$data['filename'],'列表','Xls');
  316. return $this->renderSuccess($res,'导出成功');
  317. }
  318. return $this->renderSuccess(compact('currentYear','prevYear','months'));
  319. }
  320. //商品销量排行列表
  321. public function goodsSalesRankList(){
  322. $betweenTime = $this->request->param('betweenTime');
  323. if ($betweenTime){
  324. $times = between_time($betweenTime);
  325. }else{
  326. $weekday = date('w')-1;
  327. $times['start_time'] = strtotime(date('Y-m-d',strtotime("-{$weekday} day"))) ;//当前星期的星期一
  328. $times['end_time'] = time();
  329. }
  330. if ($this->request->isPost()) { // 导出数据
  331. $model = new GoodsSalesRank();
  332. $data = $model->export($times['start_time'], $times['end_time']);
  333. if (empty($data['data'])) {
  334. return $this->renderError('暂无数据');
  335. }
  336. $res = ExportService::export($data['data'],$data['header'],$data['filename'],'列表','Xls');
  337. return $this->renderSuccess($res,'导出成功');
  338. }
  339. // 获取数据
  340. $m = new GoodsSalesRank();
  341. $list = $m->listRank($times['start_time'],$times['end_time']);
  342. return $this->renderSuccess(compact('list'));
  343. }
  344. /**
  345. *全渠道销售业绩趋势
  346. * @return array
  347. */
  348. public function channelSaleStat(){
  349. $param = $this->request->param();
  350. $betweenTime = $this->request->param('betweenTime');
  351. if ($betweenTime){
  352. $times = between_time($betweenTime);
  353. $times['start_time'] = strtotime(date('Y-m-d 00:00:00',$times['start_time']));
  354. $times['end_time'] = strtotime(date('Y-m-d 23:59:59',$times['end_time']));
  355. }else{
  356. $nowM = strtotime(date('Y-m-01 00:00:00'));
  357. $times['start_time'] =strtotime(date('Y-m-d ',strtotime('-1 month',$nowM)));
  358. $times['end_time'] = $nowM;
  359. if($param['ftype'] == 3){
  360. $times['end_time'] = $nowM - 86400;
  361. }
  362. }
  363. //dd($times);
  364. $model = new ChannelSaleVolumeTj();
  365. $volumes = $model->getList($param['ftype'],$times);
  366. $volumes = $volumes?$volumes->toArray():[];
  367. $xes = array_column($volumes,'remark');
  368. if ($param['ftype'] == 1){
  369. $xes = array_map(function($val){
  370. return substr($val,-2).'日';
  371. },$xes);
  372. }elseif($param['ftype'] == 3){
  373. $xes = array_map(function($val){
  374. return substr($val,-2).'月';
  375. },$xes);
  376. }
  377. $volumes = array_column($volumes,'sale_volume');
  378. return $this->renderSuccess(compact('volumes','xes'));
  379. }
  380. /**
  381. * 全渠道销售业绩构成
  382. * @return array
  383. */
  384. public function channelPieData(){
  385. $betweenTime = $this->request->param('betweenTime');
  386. if ($betweenTime){
  387. $times = between_time($betweenTime);
  388. $times['start_time'] = strtotime(date('Y-m-d 00:00:00',$times['start_time']));
  389. $times['end_time'] = strtotime(date('Y-m-d 23:59:59',$times['end_time']));
  390. }else{
  391. $nowM = strtotime(date('Y-m-01 00:00:00'));
  392. $times['start_time'] = mktime(0,0,0,intval(date('m')) - 1,1,intval(date('Y')));
  393. $times['end_time'] = $nowM;
  394. }
  395. $model = new ChannelSaleVolumeTj;
  396. $volumes = $model->getPieList($times);
  397. $t_volume1 = $t_volume2 = $t_volume3 = 0;
  398. $sale_volumes = array_column($volumes,'sale_volume');
  399. $t_volume = array_sum($sale_volumes);
  400. $y1 =$y2=$y3 = 0;
  401. if ($t_volume > 0){
  402. foreach ($volumes as $v){
  403. if ($v['channel_type'] == 1){
  404. $y1 = helper::bcadd(round($v['sale_volume']/$t_volume,4)*100,0,2);
  405. $t_volume1 = $v['sale_volume'];
  406. }
  407. if ($v['channel_type'] == 2){
  408. $y2 =helper::bcadd( round($v['sale_volume']/$t_volume,4)*100,0,2);
  409. $t_volume2 = $v['sale_volume'];
  410. }
  411. if ($v['channel_type'] == 3){
  412. $t_volume3 = $v['sale_volume'];
  413. }
  414. }
  415. $y3 = helper::bcsub(100 , $y1+$y2,2);
  416. }
  417. $data[] =['channel_type'=>1,'name'=>'门店渠道','value'=>$y1,'volume'=>$t_volume1];
  418. $data[] =['channel_type'=>2,'name'=>'推荐官渠道','value'=>$y2,'volume'=>$t_volume2];
  419. $data[] =['channel_type'=>3,'name'=>'自然销售渠道','value'=>$y3,'volume'=>$t_volume3];
  420. return $this->renderSuccess(compact('data'));
  421. }
  422. /**
  423. * 退款商品统计列表
  424. * @return array
  425. */
  426. public function refundGoodsStatisticsList(){
  427. // 获取数据
  428. $m = new RefundGoodsStatistics();
  429. $list = $m->getList($this->request->param());
  430. return $this->renderSuccess(compact('list'));
  431. }
  432. /**
  433. * 导出退款商品统计
  434. */
  435. public function exportRefundGoodsStatistics(){
  436. $param = $this->request->param();
  437. $model = new RefundGoodsStatistics;
  438. $data = $model->export($param);
  439. if (empty($data['data'])) {
  440. return $this->renderError('暂无数据');
  441. }
  442. $res = ExportService::export($data['data'],$data['header'],$data['filename'],'列表','Xls');
  443. return $this->renderSuccess($res,'导出成功');
  444. }
  445. /**
  446. * 商品浏览数据列表
  447. * @return array
  448. */
  449. public function goodsVisitStatisticsList(){
  450. // 获取数据
  451. $m = new GoodsVisitStatistics();
  452. $list = $m->getList($this->request->param());
  453. return $this->renderSuccess(compact('list'));
  454. }
  455. /**
  456. * 导出商品浏览数据
  457. */
  458. public function exportGoodsVisitStatistics(){
  459. $param = $this->request->param();
  460. $model = new GoodsVisitStatistics();
  461. $data = $model->export($param);
  462. if (empty($data['data'])) {
  463. return $this->renderError('暂无数据');
  464. }
  465. $res = ExportService::export($data['data'],$data['header'],$data['filename'],'列表','Xls');
  466. return $this->renderSuccess($res,'导出成功');
  467. }
  468. /**
  469. * 商品销售数据列表
  470. * @return array
  471. */
  472. public function goodsSaleStatisticsList(){
  473. // 获取数据
  474. $m = new GoodsSaleStatistics();
  475. $list = $m->getList($this->request->param());
  476. return $this->renderSuccess(compact('list'));
  477. }
  478. /**
  479. * 导出商品销售数据
  480. */
  481. public function exportGoodsSaleStatistics(){
  482. $param = $this->request->param();
  483. $model = new GoodsSaleStatistics();
  484. $data = $model->export($param);
  485. if (empty($data['data'])) {
  486. return $this->renderError('暂无数据');
  487. }
  488. $res = ExportService::export($data['data'],$data['header'],$data['filename'],'列表','Xls');
  489. return $this->renderSuccess($res,'导出成功');
  490. }
  491. /**
  492. * 渠道销售数据列表
  493. * @return array
  494. */
  495. public function channelSaleStatisticsList(){
  496. $param = $this->request->param();
  497. $model = new ChannelSaleStatistics();
  498. if ($this->request->isPost()) { // 导出数据
  499. $data = $model->export($param);
  500. if (empty($data['data'])) {
  501. return $this->renderError('暂无数据');
  502. }
  503. $res = ExportService::export($data['data'],$data['header'],$data['filename'],'列表','Xls');
  504. return $this->renderSuccess($res,'导出成功');
  505. }
  506. $list = $model->getList($param);
  507. return $this->renderSuccess(compact('list'));
  508. }
  509. }