Report.php 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. <?php
  2. namespace app\badminapi\controller;
  3. use app\models\merchant\Merchant;
  4. use app\models\store\StoreOrder;
  5. use app\models\store\StoreProduct;
  6. use app\models\store\StoreProductAttrValue;
  7. use app\models\system\MerchantDailyReport;
  8. use app\models\system\SystemDailyReport;
  9. use app\models\user\User;
  10. use crmeb\basic\BaseModel;
  11. use crmeb\services\UtilService;
  12. use crmeb\traits\ModelTrait;
  13. use Exception;
  14. use think\db\exception\DbException;
  15. /**
  16. * 报表控制器
  17. * Class Report
  18. * @package app\adminapi\controller
  19. */
  20. class Report extends AuthController
  21. {
  22. public function initialize()
  23. {
  24. parent::initialize(); // TODO: Change the autogenerated stub
  25. }
  26. use ModelTrait;
  27. /**
  28. * 手动生成昨日报表
  29. * @return mixed
  30. */
  31. public function createYesterdayReport()
  32. {
  33. try {
  34. MerchantDailyReport::recordYesterdayReport();
  35. SystemDailyReport::recordYesterdayReport();
  36. BaseModel::commitTrans();
  37. return app('json')->success('生成成功');
  38. } catch (DbException $e) {
  39. BaseModel::rollbackTrans();
  40. return app('json')->fail($e->getMessage());
  41. }
  42. }
  43. /**
  44. * 系统报表
  45. * @return mixed
  46. * @throws Exception
  47. */
  48. public function systemReportList()
  49. {
  50. list($page, $limit) = UtilService::getMore([['page', 1], ['limit', 10]], $this->request, true);
  51. //今日系统报表
  52. $today = [
  53. 'today_reg' => User::whereDay('add_time', 'today')->count(),
  54. 'today_visit' => User::whereDay('last_time', 'today')->count(),
  55. 'today_order' => StoreOrder::whereDay('add_time', 'today')->count(),
  56. 'today_order_money' => StoreOrder::where('paid', 1)
  57. ->where('is_del', 0)
  58. ->where('refund_status', 0)
  59. ->whereDay('pay_time', 'today')
  60. ->sum('pay_price')
  61. ];
  62. $pass_list = SystemDailyReport::order('report_date', 'desc')->page($page, $limit)->select();
  63. if (count($pass_list) > 0) {
  64. $pass_list->toArray();
  65. } else {
  66. $pass_list = [];
  67. }
  68. return app('json')->success('ok', compact('today', 'pass_list'));
  69. }
  70. /**
  71. * 商户报表
  72. * @return mixed
  73. * @throws Exception
  74. */
  75. public function merchantReportList()
  76. {
  77. list($page, $limit, $mer_id, $date) = UtilService::getMore([
  78. ['page', 1],
  79. ['limit', 10],
  80. ['mer_id', ''],
  81. ['date', '']
  82. ], $this->request, true);
  83. if ($mer_id) {
  84. if (!Merchant::be($mer_id)) {
  85. return app('json')->fail('无此商户');
  86. }
  87. //今日系统报表
  88. $today = [
  89. 'today_reg' => User::merSet($mer_id)->whereDay('add_time', 'today')->count(),
  90. 'today_visit' => User::merSet($mer_id)->whereDay('last_time', 'today')->count(),
  91. 'today_order' => StoreOrder::merSet($mer_id)->whereDay('add_time', 'today')->count(),
  92. 'today_order_money' => StoreOrder::where('mer_id', $mer_id)
  93. ->where('paid', 1)
  94. ->where('is_del', 0)
  95. ->where('refund_status', 0)
  96. ->whereDay('pay_time', 'today')
  97. ->sum('pay_price')
  98. ];
  99. }
  100. $model = MerchantDailyReport::order('report_date', 'desc');
  101. if ($mer_id) {
  102. $model->where('mer_id', $mer_id);
  103. }
  104. if ($date) {
  105. list($startTime, $endTime) = explode('-', $date);
  106. $model = $model->where('report_date', '>=', $startTime);
  107. $model = $model->where('report_date', '<=', $endTime);
  108. }
  109. $pass_list = $model->page($page, $limit)->select();
  110. if (count($pass_list) > 0) {
  111. $pass_list->toArray();
  112. } else {
  113. $pass_list = [];
  114. }
  115. return app('json')->success('ok', isset($today) ? compact('today', 'pass_list') : ['pass_list' => $pass_list]);
  116. }
  117. /**
  118. * 商户排行
  119. * @param $type
  120. * @param $sort
  121. * @return mixed
  122. * @throws Exception
  123. */
  124. public function merchantRank($type, $sort)
  125. {
  126. if (!in_array(strtolower($type), ['sum_reg', 'sum_visit', 'sum_order', 'sum_order_money'])) {
  127. return app('json')->fail('查询的排行键值有误');
  128. }
  129. if (!in_array(strtolower($sort), ['desc', 'asc'])) {
  130. return app('json')->fail('查询的排行方式有误');
  131. }
  132. list($page, $limit) = UtilService::getMore([['page', 1], ['limit', 10]], $this->request, true);
  133. $report = MerchantDailyReport::alias('r')->group('mer_id')
  134. ->field('r.mer_id, m.name, m.logo, SUM(r.today_reg) as sum_reg,SUM(r.today_visit) as sum_visit,SUM(r.today_order) as sum_order,SUM(r.today_order_money) as sum_order_money')
  135. ->join('merchant m', 'r.mer_id = m.id')
  136. ->order(strtolower($type), strtolower($sort))
  137. ->page($page, $limit)->select();
  138. foreach($report as $key => $value) {
  139. $value['id'] = $key + 1;
  140. }
  141. return app('json')->success('ok', $report ? $report->toArray() : []);
  142. }
  143. /**
  144. * 首页头部统计数据
  145. * @return mixed
  146. */
  147. public function homeStatics($mer_id)
  148. {
  149. //TODO 销售额
  150. //今日销售额
  151. $today_sales = StoreOrder::merSet($mer_id)
  152. ->where('paid', 1)
  153. ->where('is_del', 0)
  154. ->where('refund_status', 0)
  155. ->whereDay('pay_time')
  156. ->sum('pay_price');
  157. //昨日销售额
  158. $yesterday_sales = StoreOrder::merSet($mer_id)
  159. ->where('paid', 1)
  160. ->where('is_del', 0)
  161. ->where('refund_status', 0)
  162. ->whereDay('pay_time', 'yesterday')
  163. ->sum('pay_price');
  164. //日同比
  165. $sales_today_ratio = $this->growth($today_sales, $yesterday_sales);
  166. //周销售额
  167. //本周
  168. $this_week_sales = StoreOrder::merSet($mer_id)
  169. ->where('paid', 1)
  170. ->where('is_del', 0)
  171. ->where('refund_status', 0)
  172. ->whereWeek('pay_time')
  173. ->sum('pay_price');
  174. //上周
  175. $last_week_sales = StoreOrder::merSet($mer_id)
  176. ->where('paid', 1)
  177. ->where('is_del', 0)
  178. ->where('refund_status', 0)
  179. ->whereWeek('pay_time', 'last week')
  180. ->sum('pay_price');
  181. //周同比
  182. $sales_week_ratio = $this->growth($this_week_sales, $last_week_sales);
  183. //总销售额
  184. $total_sales = StoreOrder::merSet($mer_id)
  185. ->where('paid', 1)
  186. ->where('is_del', 0)
  187. ->where('refund_status', 0)
  188. ->sum('pay_price');
  189. $sales = [
  190. 'today' => $today_sales,
  191. 'yesterday' => $yesterday_sales,
  192. 'today_ratio' => $sales_today_ratio,
  193. 'week' => $this_week_sales,
  194. 'last_week' => $last_week_sales,
  195. 'week_ratio' => $sales_week_ratio,
  196. 'total' => $total_sales . '元',
  197. 'date' => '昨日'
  198. ];
  199. //TODO:用户访问量
  200. //今日访问量
  201. $today_visits = User::merSet($mer_id)->WhereDay('last_time')->count();
  202. //昨日访问量
  203. $yesterday_visits = User::merSet($mer_id)->whereDay('last_time', 'yesterday')->count();
  204. //日同比
  205. $visits_today_ratio = $this->growth($today_visits, $yesterday_visits);
  206. //本周访问量
  207. $this_week_visits = User::merSet($mer_id)->WhereWeek('last_time')->count();
  208. //上周访问量
  209. $last_week_visits = User::merSet($mer_id)->WhereWeek('last_time', 'last week')->count();
  210. //周同比
  211. $visits_week_ratio = $this->growth($this_week_visits, $last_week_visits);
  212. //总访问量
  213. $total_visits = User::merSet($mer_id)->count();
  214. $visits = [
  215. 'today' => $today_visits,
  216. 'yesterday' => $yesterday_visits,
  217. 'today_ratio' => $visits_today_ratio,
  218. 'week' => $this_week_visits,
  219. 'last_week' => $last_week_visits,
  220. 'week_ratio' => $visits_week_ratio,
  221. 'total' => $total_visits . 'Pv',
  222. 'date' => '昨日'
  223. ];
  224. //TODO 订单量
  225. //今日订单量
  226. $today_order = StoreOrder::merSet($mer_id)->whereDay('add_time')->count();
  227. //昨日订单量
  228. $yesterday_order = StoreOrder::merSet($mer_id)->whereDay('add_time', 'yesterday')->count();
  229. //订单日同比
  230. $order_today_ratio = $this->growth($today_order, $yesterday_order);
  231. //本周订单量
  232. $this_week_order = StoreOrder::merSet($mer_id)->whereWeek('add_time')->count();
  233. //上周订单量
  234. $last_week_order = StoreOrder::merSet($mer_id)->whereWeek('add_time', 'last week')->count();
  235. //订单周同比
  236. $order_week_ratio = $this->growth($this_week_order, $last_week_order);
  237. //总订单量
  238. $total_order = StoreOrder::merSet($mer_id)->where('is_system_del', 0)->count();
  239. $order = [
  240. 'today' => $today_order,
  241. 'yesterday' => $yesterday_order,
  242. 'today_ratio' => $order_today_ratio,
  243. 'week' => $this_week_order,
  244. 'last_week' => $last_week_order,
  245. 'week_ratio' => $order_week_ratio,
  246. 'total' => $total_order . '单',
  247. 'date' => '昨日'
  248. ];
  249. //TODO 用户
  250. //今日新增用户
  251. $today_user = User::merSet($mer_id)->whereDay('add_time')->count();
  252. //昨日新增用户
  253. $yesterday_user = User::merSet($mer_id)->whereDay('add_time', 'yesterday')->count();
  254. //新增用户日同比
  255. $user_today_ratio = $this->growth($today_user, $yesterday_user);
  256. //本周新增用户
  257. $this_week_user = User::merSet($mer_id)->whereWeek('add_time')->count();
  258. //上周新增用户
  259. $last_week_user = User::merSet($mer_id)->whereWeek('add_time', 'last week')->count();
  260. //新增用户周同比
  261. $user_week_ratio = $this->growth($this_week_user, $last_week_user);
  262. //所有用户
  263. $total_user = User::merSet($mer_id)->count();
  264. $user = [
  265. 'today' => $today_user,
  266. 'yesterday' => $yesterday_user,
  267. 'today_ratio' => $user_today_ratio,
  268. 'week' => $this_week_user,
  269. 'last_week' => $last_week_user,
  270. 'week_ratio' => $user_week_ratio,
  271. 'total' => $total_user . '人',
  272. 'date' => '昨日'
  273. ];
  274. // $qrcode = MerchantMiniprogram::vaildWhere()->where('mer_id', $this->merId)->field('test_qrcode_url,qrcode_url')->find();
  275. $info = array_values(compact('sales', 'visits', 'order', 'user'));
  276. $info[0]['title'] = '销售额';
  277. $info[1]['title'] = '用户访问量';
  278. $info[2]['title'] = '订单量';
  279. $info[3]['title'] = '新增用户';
  280. $info[0]['total_name'] = '总销售额';
  281. $info[1]['total_name'] = '总访问量';
  282. $info[2]['total_name'] = '总订单量';
  283. $info[3]['total_name'] = '总用户';
  284. return $this->success(compact('info'));
  285. }
  286. //增长率
  287. public function growth($left, $right)
  288. {
  289. if ($right)
  290. $ratio = bcmul(bcdiv(bcsub($left, $right, 2), $right, 4), 100, 2);
  291. else {
  292. if ($left)
  293. $ratio = 100;
  294. else
  295. $ratio = 0;
  296. }
  297. return $ratio;
  298. }
  299. /**
  300. * 订单图表
  301. */
  302. public function orderChart($mer_id)
  303. {
  304. $cycle = $this->request->param('cycle') ?: 'thirtyday';//默认30天
  305. $datalist = [];
  306. switch ($cycle) {
  307. case 'thirtyday':
  308. $datebefor = date('Y-m-d', strtotime('-30 day'));
  309. $dateafter = date('Y-m-d');
  310. //上期
  311. $pre_datebefor = date('Y-m-d', strtotime('-60 day'));
  312. $pre_dateafter = date('Y-m-d', strtotime('-30 day'));
  313. for ($i = -30; $i < 0; $i++) {
  314. $datalist[date('m-d', strtotime($i . ' day'))] = date('m-d', strtotime($i . ' day'));
  315. }
  316. $order_list = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$datebefor, $dateafter])
  317. ->field("FROM_UNIXTIME(add_time,'%m-%d') as day,count(*) as count,sum(pay_price) as price")
  318. ->group("FROM_UNIXTIME(add_time, '%Y%m%d')")
  319. ->order('add_time asc')
  320. ->select()->toArray();
  321. if (empty($order_list)) return app('json')->success();
  322. foreach ($order_list as $k => &$v) {
  323. $order_list[$v['day']] = $v;
  324. }
  325. $cycle_list = [];
  326. foreach ($datalist as $dk => $dd) {
  327. if (!empty($order_list[$dd])) {
  328. $cycle_list[$dd] = $order_list[$dd];
  329. } else {
  330. $cycle_list[$dd] = ['count' => 0, 'day' => $dd, 'price' => ''];
  331. }
  332. }
  333. $chartdata = [];
  334. $data = [];//临时
  335. $chartdata['yAxis']['maxnum'] = 0;//最大值数量
  336. $chartdata['yAxis']['maxprice'] = 0;//最大值金额
  337. foreach ($cycle_list as $k => $v) {
  338. $data['day'][] = $v['day'];
  339. $data['count'][] = $v['count'];
  340. $data['price'][] = round($v['price'], 2);
  341. if ($chartdata['yAxis']['maxnum'] < $v['count'])
  342. $chartdata['yAxis']['maxnum'] = $v['count'];//日最大订单数
  343. if ($chartdata['yAxis']['maxprice'] < $v['price'])
  344. $chartdata['yAxis']['maxprice'] = $v['price'];//日最大金额
  345. }
  346. $chartdata['legend'] = ['订单金额', '订单数'];//分类
  347. $chartdata['xAxis'] = $data['day'];//X轴值
  348. //,'itemStyle'=>$series
  349. // $series = ['normal' => ['label' => ['show' => true, 'position' => 'top']]];
  350. $series1 = ['normal' => ['color' => [
  351. 'x' => 0, 'y' => 0, 'x2' => 0, 'y2' => 1,
  352. 'colorStops' => [
  353. [
  354. 'offset' => 0,
  355. 'color' => '#69cdff'
  356. ],
  357. [
  358. 'offset' => 0.5,
  359. 'color' => '#3eb3f7'
  360. ],
  361. [
  362. 'offset' => 1,
  363. 'color' => '#1495eb'
  364. ]
  365. ]
  366. ]]
  367. ];
  368. $series2 = ['normal' => ['color' => [
  369. 'x' => 0, 'y' => 0, 'x2' => 0, 'y2' => 1,
  370. 'colorStops' => [
  371. [
  372. 'offset' => 0,
  373. 'color' => '#6fdeab'
  374. ],
  375. [
  376. 'offset' => 0.5,
  377. 'color' => '#44d693'
  378. ],
  379. [
  380. 'offset' => 1,
  381. 'color' => '#2cc981'
  382. ]
  383. ]
  384. ]]
  385. ];
  386. $chartdata['series'][] = ['name' => $chartdata['legend'][0], 'type' => 'bar', 'itemStyle' => $series1, 'data' => $data['price']];//分类1值
  387. $chartdata['series'][] = ['name' => $chartdata['legend'][1], 'type' => 'bar', 'itemStyle' => $series2, 'data' => $data['count']];//分类2值
  388. //统计总数上期
  389. $pre_total = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$pre_datebefor, $pre_dateafter])
  390. ->field("count(*) as count,sum(pay_price) as price")
  391. ->find();
  392. if ($pre_total) {
  393. $chartdata['pre_cycle']['count'] = [
  394. 'data' => $pre_total['count'] ?: 0
  395. ];
  396. $chartdata['pre_cycle']['price'] = [
  397. 'data' => $pre_total['price'] ?: 0
  398. ];
  399. }
  400. //统计总数
  401. $total = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$datebefor, $dateafter])
  402. ->field("count(*) as count,sum(pay_price) as price")
  403. ->find();
  404. if ($total) {
  405. $cha_count = intval($pre_total['count']) - intval($total['count']);
  406. $pre_total['count'] = $pre_total['count'] == 0 ? 1 : $pre_total['count'];
  407. $chartdata['cycle']['count'] = [
  408. 'data' => $total['count'] ?: 0,
  409. 'percent' => round((abs($cha_count) / intval($pre_total['count']) * 100), 2),
  410. 'is_plus' => $cha_count > 0 ? -1 : ($cha_count == 0 ? 0 : 1)
  411. ];
  412. $cha_price = round($pre_total['price'], 2) - round($total['price'], 2);
  413. $pre_total['price'] = $pre_total['price'] == 0 ? 1 : $pre_total['price'];
  414. $chartdata['cycle']['price'] = [
  415. 'data' => $total['price'] ?: 0,
  416. 'percent' => round(abs($cha_price) / $pre_total['price'] * 100, 2),
  417. 'is_plus' => $cha_price > 0 ? -1 : ($cha_price == 0 ? 0 : 1)
  418. ];
  419. }
  420. return $this->success($chartdata);
  421. break;
  422. case 'week':
  423. $weekarray = array(['周日'], ['周一'], ['周二'], ['周三'], ['周四'], ['周五'], ['周六']);
  424. $datebefor = date('Y-m-d', strtotime('-1 week Monday'));
  425. $dateafter = date('Y-m-d', strtotime('-1 week Sunday'));
  426. $order_list = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$datebefor, $dateafter])
  427. ->field("FROM_UNIXTIME(add_time,'%w') as day,count(*) as count,sum(pay_price) as price")
  428. ->group("FROM_UNIXTIME(add_time, '%Y%m%e')")
  429. ->order('add_time asc')
  430. ->select()->toArray();
  431. //数据查询重新处理
  432. $new_order_list = [];
  433. foreach ($order_list as $k => $v) {
  434. $new_order_list[$v['day']] = $v;
  435. }
  436. $now_datebefor = date('Y-m-d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600));
  437. $now_dateafter = date('Y-m-d', strtotime("+1 day"));
  438. $now_order_list = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$now_datebefor, $now_dateafter])
  439. ->field("FROM_UNIXTIME(add_time,'%w') as day,count(*) as count,sum(pay_price) as price")
  440. ->group("FROM_UNIXTIME(add_time, '%Y%m%e')")
  441. ->order('add_time asc')
  442. ->select()->toArray();
  443. //数据查询重新处理 key 变为当前值
  444. $new_now_order_list = [];
  445. foreach ($now_order_list as $k => $v) {
  446. $new_now_order_list[$v['day']] = $v;
  447. }
  448. foreach ($weekarray as $dk => $dd) {
  449. if (!empty($new_order_list[$dk])) {
  450. $weekarray[$dk]['pre'] = $new_order_list[$dk];
  451. } else {
  452. $weekarray[$dk]['pre'] = ['count' => 0, 'day' => $weekarray[$dk][0], 'price' => '0'];
  453. }
  454. if (!empty($new_now_order_list[$dk])) {
  455. $weekarray[$dk]['now'] = $new_now_order_list[$dk];
  456. } else {
  457. $weekarray[$dk]['now'] = ['count' => 0, 'day' => $weekarray[$dk][0], 'price' => '0'];
  458. }
  459. }
  460. $chartdata = [];
  461. $data = [];//临时
  462. $chartdata['yAxis']['maxnum'] = 0;//最大值数量
  463. $chartdata['yAxis']['maxprice'] = 0;//最大值金额
  464. foreach ($weekarray as $k => $v) {
  465. $data['day'][] = $v[0];
  466. $data['pre']['count'][] = $v['pre']['count'];
  467. $data['pre']['price'][] = round($v['pre']['price'], 2);
  468. $data['now']['count'][] = $v['now']['count'];
  469. $data['now']['price'][] = round($v['now']['price'], 2);
  470. if ($chartdata['yAxis']['maxnum'] < $v['pre']['count'] || $chartdata['yAxis']['maxnum'] < $v['now']['count']) {
  471. $chartdata['yAxis']['maxnum'] = $v['pre']['count'] > $v['now']['count'] ? $v['pre']['count'] : $v['now']['count'];//日最大订单数
  472. }
  473. if ($chartdata['yAxis']['maxprice'] < $v['pre']['price'] || $chartdata['yAxis']['maxprice'] < $v['now']['price']) {
  474. $chartdata['yAxis']['maxprice'] = $v['pre']['price'] > $v['now']['price'] ? $v['pre']['price'] : $v['now']['price'];//日最大金额
  475. }
  476. }
  477. $chartdata['legend'] = ['上周金额', '本周金额', '上周订单数', '本周订单数'];//分类
  478. $chartdata['xAxis'] = $data['day'];//X轴值
  479. //,'itemStyle'=>$series
  480. // $series = ['normal' => ['label' => ['show' => true, 'position' => 'top']]];
  481. $series1 = ['normal' => ['color' => [
  482. 'x' => 0, 'y' => 0, 'x2' => 0, 'y2' => 1,
  483. 'colorStops' => [
  484. [
  485. 'offset' => 0,
  486. 'color' => '#69cdff'
  487. ],
  488. [
  489. 'offset' => 0.5,
  490. 'color' => '#3eb3f7'
  491. ],
  492. [
  493. 'offset' => 1,
  494. 'color' => '#1495eb'
  495. ]
  496. ]
  497. ]]
  498. ];
  499. $series2 = ['normal' => ['color' => [
  500. 'x' => 0, 'y' => 0, 'x2' => 0, 'y2' => 1,
  501. 'colorStops' => [
  502. [
  503. 'offset' => 0,
  504. 'color' => '#6fdeab'
  505. ],
  506. [
  507. 'offset' => 0.5,
  508. 'color' => '#44d693'
  509. ],
  510. [
  511. 'offset' => 1,
  512. 'color' => '#2cc981'
  513. ]
  514. ]
  515. ]]
  516. ];
  517. $chartdata['series'][] = ['name' => $chartdata['legend'][0], 'type' => 'bar', 'itemStyle' => $series1, 'data' => $data['pre']['price']];//分类1值
  518. $chartdata['series'][] = ['name' => $chartdata['legend'][1], 'type' => 'bar', 'itemStyle' => $series1, 'data' => $data['now']['price']];//分类1值
  519. $chartdata['series'][] = ['name' => $chartdata['legend'][2], 'type' => 'line', 'itemStyle' => $series2, 'data' => $data['pre']['count']];//分类2值
  520. $chartdata['series'][] = ['name' => $chartdata['legend'][3], 'type' => 'line', 'itemStyle' => $series2, 'data' => $data['now']['count']];//分类2值
  521. //统计总数上期
  522. $pre_total = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$datebefor, $dateafter])
  523. ->field("count(*) as count,sum(pay_price) as price")
  524. ->find();
  525. if ($pre_total) {
  526. $chartdata['pre_cycle']['count'] = [
  527. 'data' => $pre_total['count'] ?: 0
  528. ];
  529. $chartdata['pre_cycle']['price'] = [
  530. 'data' => $pre_total['price'] ?: 0
  531. ];
  532. }
  533. //统计总数
  534. $total = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$now_datebefor, $now_dateafter])
  535. ->field("count(*) as count,sum(pay_price) as price")
  536. ->find();
  537. if ($total) {
  538. $cha_count = intval($pre_total['count']) - intval($total['count']);
  539. $pre_total['count'] = $pre_total['count'] == 0 ? 1 : $pre_total['count'];
  540. $chartdata['cycle']['count'] = [
  541. 'data' => $total['count'] ?: 0,
  542. 'percent' => round((abs($cha_count) / intval($pre_total['count']) * 100), 2),
  543. 'is_plus' => $cha_count > 0 ? -1 : ($cha_count == 0 ? 0 : 1)
  544. ];
  545. $cha_price = round($pre_total['price'], 2) - round($total['price'], 2);
  546. $pre_total['price'] = $pre_total['price'] == 0 ? 1 : $pre_total['price'];
  547. $chartdata['cycle']['price'] = [
  548. 'data' => $total['price'] ?: 0,
  549. 'percent' => round(abs($cha_price) / $pre_total['price'] * 100, 2),
  550. 'is_plus' => $cha_price > 0 ? -1 : ($cha_price == 0 ? 0 : 1)
  551. ];
  552. }
  553. return $this->success($chartdata);
  554. break;
  555. case 'month':
  556. $weekarray = array('01' => ['1'], '02' => ['2'], '03' => ['3'], '04' => ['4'], '05' => ['5'], '06' => ['6'], '07' => ['7'], '08' => ['8'], '09' => ['9'], '10' => ['10'], '11' => ['11'], '12' => ['12'], '13' => ['13'], '14' => ['14'], '15' => ['15'], '16' => ['16'], '17' => ['17'], '18' => ['18'], '19' => ['19'], '20' => ['20'], '21' => ['21'], '22' => ['22'], '23' => ['23'], '24' => ['24'], '25' => ['25'], '26' => ['26'], '27' => ['27'], '28' => ['28'], '29' => ['29'], '30' => ['30'], '31' => ['31']);
  557. $datebefor = date('Y-m-01', strtotime('-1 month'));
  558. $dateafter = date('Y-m-d', strtotime(date('Y-m-01')));
  559. $order_list = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$datebefor, $dateafter])
  560. ->field("FROM_UNIXTIME(add_time,'%d') as day,count(*) as count,sum(pay_price) as price")
  561. ->group("FROM_UNIXTIME(add_time, '%Y%m%e')")
  562. ->order('add_time asc')
  563. ->select()->toArray();
  564. //数据查询重新处理
  565. $new_order_list = [];
  566. foreach ($order_list as $k => $v) {
  567. $new_order_list[$v['day']] = $v;
  568. }
  569. $now_datebefor = date('Y-m-01');
  570. $now_dateafter = date('Y-m-d', strtotime("+1 day"));
  571. $now_order_list = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$now_datebefor, $now_dateafter])
  572. ->field("FROM_UNIXTIME(add_time,'%d') as day,count(*) as count,sum(pay_price) as price")
  573. ->group("FROM_UNIXTIME(add_time, '%Y%m%e')")
  574. ->order('add_time asc')
  575. ->select()->toArray();
  576. //数据查询重新处理 key 变为当前值
  577. $new_now_order_list = [];
  578. foreach ($now_order_list as $k => $v) {
  579. $new_now_order_list[$v['day']] = $v;
  580. }
  581. foreach ($weekarray as $dk => $dd) {
  582. if (!empty($new_order_list[$dk])) {
  583. $weekarray[$dk]['pre'] = $new_order_list[$dk];
  584. } else {
  585. $weekarray[$dk]['pre'] = ['count' => 0, 'day' => $weekarray[$dk][0], 'price' => '0'];
  586. }
  587. if (!empty($new_now_order_list[$dk])) {
  588. $weekarray[$dk]['now'] = $new_now_order_list[$dk];
  589. } else {
  590. $weekarray[$dk]['now'] = ['count' => 0, 'day' => $weekarray[$dk][0], 'price' => '0'];
  591. }
  592. }
  593. $chartdata = [];
  594. $data = [];//临时
  595. $chartdata['yAxis']['maxnum'] = 0;//最大值数量
  596. $chartdata['yAxis']['maxprice'] = 0;//最大值金额
  597. foreach ($weekarray as $k => $v) {
  598. $data['day'][] = $v[0];
  599. $data['pre']['count'][] = $v['pre']['count'];
  600. $data['pre']['price'][] = round($v['pre']['price'], 2);
  601. $data['now']['count'][] = $v['now']['count'];
  602. $data['now']['price'][] = round($v['now']['price'], 2);
  603. if ($chartdata['yAxis']['maxnum'] < $v['pre']['count'] || $chartdata['yAxis']['maxnum'] < $v['now']['count']) {
  604. $chartdata['yAxis']['maxnum'] = $v['pre']['count'] > $v['now']['count'] ? $v['pre']['count'] : $v['now']['count'];//日最大订单数
  605. }
  606. if ($chartdata['yAxis']['maxprice'] < $v['pre']['price'] || $chartdata['yAxis']['maxprice'] < $v['now']['price']) {
  607. $chartdata['yAxis']['maxprice'] = $v['pre']['price'] > $v['now']['price'] ? $v['pre']['price'] : $v['now']['price'];//日最大金额
  608. }
  609. }
  610. $chartdata['legend'] = ['上月金额', '本月金额', '上月订单数', '本月订单数'];//分类
  611. $chartdata['xAxis'] = $data['day'];//X轴值
  612. //,'itemStyle'=>$series
  613. // $series = ['normal' => ['label' => ['show' => true, 'position' => 'top']]];
  614. $series1 = ['normal' => ['color' => [
  615. 'x' => 0, 'y' => 0, 'x2' => 0, 'y2' => 1,
  616. 'colorStops' => [
  617. [
  618. 'offset' => 0,
  619. 'color' => '#69cdff'
  620. ],
  621. [
  622. 'offset' => 0.5,
  623. 'color' => '#3eb3f7'
  624. ],
  625. [
  626. 'offset' => 1,
  627. 'color' => '#1495eb'
  628. ]
  629. ]
  630. ]]
  631. ];
  632. $series2 = ['normal' => ['color' => [
  633. 'x' => 0, 'y' => 0, 'x2' => 0, 'y2' => 1,
  634. 'colorStops' => [
  635. [
  636. 'offset' => 0,
  637. 'color' => '#6fdeab'
  638. ],
  639. [
  640. 'offset' => 0.5,
  641. 'color' => '#44d693'
  642. ],
  643. [
  644. 'offset' => 1,
  645. 'color' => '#2cc981'
  646. ]
  647. ]
  648. ]]
  649. ];
  650. $chartdata['series'][] = ['name' => $chartdata['legend'][0], 'type' => 'bar', 'itemStyle' => $series1, 'data' => $data['pre']['price']];//分类1值
  651. $chartdata['series'][] = ['name' => $chartdata['legend'][1], 'type' => 'bar', 'itemStyle' => $series1, 'data' => $data['now']['price']];//分类1值
  652. $chartdata['series'][] = ['name' => $chartdata['legend'][2], 'type' => 'line', 'itemStyle' => $series2, 'data' => $data['pre']['count']];//分类2值
  653. $chartdata['series'][] = ['name' => $chartdata['legend'][3], 'type' => 'line', 'itemStyle' => $series2, 'data' => $data['now']['count']];//分类2值
  654. //统计总数上期
  655. $pre_total = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$datebefor, $dateafter])
  656. ->field("count(*) as count,sum(pay_price) as price")
  657. ->find();
  658. if ($pre_total) {
  659. $chartdata['pre_cycle']['count'] = [
  660. 'data' => $pre_total['count'] ?: 0
  661. ];
  662. $chartdata['pre_cycle']['price'] = [
  663. 'data' => $pre_total['price'] ?: 0
  664. ];
  665. }
  666. //统计总数
  667. $total = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$now_datebefor, $now_dateafter])
  668. ->field("count(*) as count,sum(pay_price) as price")
  669. ->find();
  670. if ($total) {
  671. $cha_count = intval($pre_total['count']) - intval($total['count']);
  672. $pre_total['count'] = $pre_total['count'] == 0 ? 1 : $pre_total['count'];
  673. $chartdata['cycle']['count'] = [
  674. 'data' => $total['count'] ?: 0,
  675. 'percent' => round((abs($cha_count) / intval($pre_total['count']) * 100), 2),
  676. 'is_plus' => $cha_count > 0 ? -1 : ($cha_count == 0 ? 0 : 1)
  677. ];
  678. $cha_price = round($pre_total['price'], 2) - round($total['price'], 2);
  679. $pre_total['price'] = $pre_total['price'] == 0 ? 1 : $pre_total['price'];
  680. $chartdata['cycle']['price'] = [
  681. 'data' => $total['price'] ?: 0,
  682. 'percent' => round(abs($cha_price) / $pre_total['price'] * 100, 2),
  683. 'is_plus' => $cha_price > 0 ? -1 : ($cha_price == 0 ? 0 : 1)
  684. ];
  685. }
  686. return $this->success($chartdata);
  687. break;
  688. case 'year':
  689. $weekarray = array('01' => ['一月'], '02' => ['二月'], '03' => ['三月'], '04' => ['四月'], '05' => ['五月'], '06' => ['六月'], '07' => ['七月'], '08' => ['八月'], '09' => ['九月'], '10' => ['十月'], '11' => ['十一月'], '12' => ['十二月']);
  690. $datebefor = date('Y-01-01', strtotime('-1 year'));
  691. $dateafter = date('Y-12-31', strtotime('-1 year'));
  692. $order_list = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$datebefor, $dateafter])
  693. ->field("FROM_UNIXTIME(add_time,'%m') as day,count(*) as count,sum(pay_price) as price")
  694. ->group("FROM_UNIXTIME(add_time, '%Y%m')")
  695. ->order('add_time asc')
  696. ->select()->toArray();
  697. //数据查询重新处理
  698. $new_order_list = [];
  699. foreach ($order_list as $k => $v) {
  700. $new_order_list[$v['day']] = $v;
  701. }
  702. $now_datebefor = date('Y-01-01');
  703. $now_dateafter = date('Y-m-d');
  704. $now_order_list = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$now_datebefor, $now_dateafter])
  705. ->field("FROM_UNIXTIME(add_time,'%m') as day,count(*) as count,sum(pay_price) as price")
  706. ->group("FROM_UNIXTIME(add_time, '%Y%m')")
  707. ->order('add_time asc')
  708. ->select()->toArray();
  709. //数据查询重新处理 key 变为当前值
  710. $new_now_order_list = [];
  711. foreach ($now_order_list as $k => $v) {
  712. $new_now_order_list[$v['day']] = $v;
  713. }
  714. foreach ($weekarray as $dk => $dd) {
  715. if (!empty($new_order_list[$dk])) {
  716. $weekarray[$dk]['pre'] = $new_order_list[$dk];
  717. } else {
  718. $weekarray[$dk]['pre'] = ['count' => 0, 'day' => $weekarray[$dk][0], 'price' => '0'];
  719. }
  720. if (!empty($new_now_order_list[$dk])) {
  721. $weekarray[$dk]['now'] = $new_now_order_list[$dk];
  722. } else {
  723. $weekarray[$dk]['now'] = ['count' => 0, 'day' => $weekarray[$dk][0], 'price' => '0'];
  724. }
  725. }
  726. $chartdata = [];
  727. $data = [];//临时
  728. $chartdata['yAxis']['maxnum'] = 0;//最大值数量
  729. $chartdata['yAxis']['maxprice'] = 0;//最大值金额
  730. foreach ($weekarray as $k => $v) {
  731. $data['day'][] = $v[0];
  732. $data['pre']['count'][] = $v['pre']['count'];
  733. $data['pre']['price'][] = round($v['pre']['price'], 2);
  734. $data['now']['count'][] = $v['now']['count'];
  735. $data['now']['price'][] = round($v['now']['price'], 2);
  736. if ($chartdata['yAxis']['maxnum'] < $v['pre']['count'] || $chartdata['yAxis']['maxnum'] < $v['now']['count']) {
  737. $chartdata['yAxis']['maxnum'] = $v['pre']['count'] > $v['now']['count'] ? $v['pre']['count'] : $v['now']['count'];//日最大订单数
  738. }
  739. if ($chartdata['yAxis']['maxprice'] < $v['pre']['price'] || $chartdata['yAxis']['maxprice'] < $v['now']['price']) {
  740. $chartdata['yAxis']['maxprice'] = $v['pre']['price'] > $v['now']['price'] ? $v['pre']['price'] : $v['now']['price'];//日最大金额
  741. }
  742. }
  743. $chartdata['legend'] = ['去年金额', '今年金额', '去年订单数', '今年订单数'];//分类
  744. $chartdata['xAxis'] = $data['day'];//X轴值
  745. //,'itemStyle'=>$series
  746. // $series = ['normal' => ['label' => ['show' => true, 'position' => 'top']]];
  747. $series1 = ['normal' => ['color' => [
  748. 'x' => 0, 'y' => 0, 'x2' => 0, 'y2' => 1,
  749. 'colorStops' => [
  750. [
  751. 'offset' => 0,
  752. 'color' => '#69cdff'
  753. ],
  754. [
  755. 'offset' => 0.5,
  756. 'color' => '#3eb3f7'
  757. ],
  758. [
  759. 'offset' => 1,
  760. 'color' => '#1495eb'
  761. ]
  762. ]
  763. ]]
  764. ];
  765. $series2 = ['normal' => ['color' => [
  766. 'x' => 0, 'y' => 0, 'x2' => 0, 'y2' => 1,
  767. 'colorStops' => [
  768. [
  769. 'offset' => 0,
  770. 'color' => '#6fdeab'
  771. ],
  772. [
  773. 'offset' => 0.5,
  774. 'color' => '#44d693'
  775. ],
  776. [
  777. 'offset' => 1,
  778. 'color' => '#2cc981'
  779. ]
  780. ]
  781. ]]
  782. ];
  783. $chartdata['series'][] = ['name' => $chartdata['legend'][0], 'type' => 'bar', 'itemStyle' => $series1, 'data' => $data['pre']['price']];//分类1值
  784. $chartdata['series'][] = ['name' => $chartdata['legend'][1], 'type' => 'bar', 'itemStyle' => $series1, 'data' => $data['now']['price']];//分类1值
  785. $chartdata['series'][] = ['name' => $chartdata['legend'][2], 'type' => 'line', 'itemStyle' => $series2, 'data' => $data['pre']['count']];//分类2值
  786. $chartdata['series'][] = ['name' => $chartdata['legend'][3], 'type' => 'line', 'itemStyle' => $series2, 'data' => $data['now']['count']];//分类2值
  787. //统计总数上期
  788. $pre_total = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$datebefor, $dateafter])
  789. ->field("count(*) as count,sum(pay_price) as price")
  790. ->find();
  791. if ($pre_total) {
  792. $chartdata['pre_cycle']['count'] = [
  793. 'data' => $pre_total['count'] ?: 0
  794. ];
  795. $chartdata['pre_cycle']['price'] = [
  796. 'data' => $pre_total['price'] ?: 0
  797. ];
  798. }
  799. //统计总数
  800. $total = StoreOrder::merSet($mer_id)->where('add_time', 'between time', [$now_datebefor, $now_dateafter])
  801. ->field("count(*) as count,sum(pay_price) as price")
  802. ->find();
  803. if ($total) {
  804. $cha_count = intval($pre_total['count']) - intval($total['count']);
  805. $pre_total['count'] = $pre_total['count'] == 0 ? 1 : $pre_total['count'];
  806. $chartdata['cycle']['count'] = [
  807. 'data' => $total['count'] ?: 0,
  808. 'percent' => round((abs($cha_count) / intval($pre_total['count']) * 100), 2),
  809. 'is_plus' => $cha_count > 0 ? -1 : ($cha_count == 0 ? 0 : 1)
  810. ];
  811. $cha_price = round($pre_total['price'], 2) - round($total['price'], 2);
  812. $pre_total['price'] = $pre_total['price'] == 0 ? 1 : $pre_total['price'];
  813. $chartdata['cycle']['price'] = [
  814. 'data' => $total['price'] ?: 0,
  815. 'percent' => round(abs($cha_price) / $pre_total['price'] * 100, 2),
  816. 'is_plus' => $cha_price > 0 ? -1 : ($cha_price == 0 ? 0 : 1)
  817. ];
  818. }
  819. return $this->success($chartdata);
  820. break;
  821. default:
  822. break;
  823. }
  824. }
  825. /**
  826. * 用户图表
  827. */
  828. public function userChart($mer_id)
  829. {
  830. $starday = date('Y-m-d', strtotime('-30 day'));
  831. $yesterday = date('Y-m-d');
  832. $user_list = User::merSet($mer_id)->where('add_time', 'between time', [$starday, $yesterday])
  833. ->field("FROM_UNIXTIME(add_time,'%m-%e') as day,count(*) as count")
  834. ->group("FROM_UNIXTIME(add_time, '%Y%m%e')")
  835. ->order('add_time asc')
  836. ->select()->toArray();
  837. $chartdata = [];
  838. $data = [];
  839. $chartdata['legend'] = ['用户数'];//分类
  840. $chartdata['yAxis']['maxnum'] = 0;//最大值数量
  841. $chartdata['xAxis'] = [date('m-d')];//X轴值
  842. $chartdata['series'] = [0];//分类1值
  843. if (!empty($user_list)) {
  844. foreach ($user_list as $k => $v) {
  845. $data['day'][] = $v['day'];
  846. $data['count'][] = $v['count'];
  847. if ($chartdata['yAxis']['maxnum'] < $v['count'])
  848. $chartdata['yAxis']['maxnum'] = $v['count'];
  849. }
  850. $chartdata['xAxis'] = $data['day'];//X轴值
  851. $chartdata['series'] = $data['count'];//分类1值
  852. }
  853. $chartdata['bing_xdata'] = ['未消费用户', '消费一次用户', '留存客户', '回流客户'];
  854. $color = ['#5cadff', '#b37feb', '#19be6b', '#ff9900'];
  855. $pay[0] = User::merSet($mer_id)->where('pay_count', 0)->count();
  856. $pay[1] = User::merSet($mer_id)->where('pay_count', 1)->count();
  857. $pay[2] = User::merSet($mer_id)->where('pay_count', '>', 0)->where('pay_count', '<', 4)->count();
  858. $pay[3] = User::merSet($mer_id)->where('pay_count', '>', 4)->count();
  859. foreach ($pay as $key => $item) {
  860. $bing_data[] = ['name' => $chartdata['bing_xdata'][$key], 'value' => $pay[$key], 'itemStyle' => ['color' => $color[$key]]];
  861. }
  862. $chartdata['bing_data'] = $bing_data;
  863. return $this->success($chartdata);
  864. }
  865. /**
  866. * 交易额排行
  867. * @return mixed
  868. */
  869. public function purchaseRanking($mer_id)
  870. {
  871. $dlist = StoreProductAttrValue::alias('v')
  872. ->where('p.mer_id', $mer_id)
  873. ->join('store_product p', 'v.product_id=p.id')
  874. ->field('v.product_id,p.store_name,sum(v.sales * v.price) as val')->group('v.product_id')->order('val', 'desc')->limit(20)->select()->toArray();
  875. $slist = StoreProduct::merSet($mer_id)->field('id as product_id,store_name,sales * price as val')->where('is_del', 0)->order('val', 'desc')->limit(20)->select()->toArray();
  876. $data = array_merge($dlist, $slist);
  877. $last_names = array_column($data, 'val');
  878. array_multisort($last_names, SORT_DESC, $data);
  879. $list = array_splice($data, 0, 20);
  880. return $this->success(compact('list'));
  881. }
  882. }