chore: 添加静态资源文件和版本配置文件
添加大量图片、字体、音频等静态资源文件,包括用户界面图片、模板文件和安装界面素材 添加系统版本配置文件(.version)和常量定义文件(.constant) 更新供应商依赖文件,包括Symfony VarDumper组件和相关许可证文件 添加验证码配置文件(captcha.php)和.gitignore规则
This commit is contained in:
197
app/services/statistic/OrderStatisticServices.php
Normal file
197
app/services/statistic/OrderStatisticServices.php
Normal file
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\services\statistic;
|
||||
|
||||
use app\services\BaseServices;
|
||||
use app\services\order\StoreOrderRefundServices;
|
||||
use app\services\order\StoreOrderServices;
|
||||
use crmeb\exceptions\AdminException;
|
||||
|
||||
|
||||
class OrderStatisticServices extends BaseServices
|
||||
{
|
||||
/**
|
||||
* 订单统计基础
|
||||
* @param $where
|
||||
* @return array
|
||||
*/
|
||||
public function getBasic($where)
|
||||
{
|
||||
$supplier_id = $where['supplier_id'] ?? '';
|
||||
/** @var StoreOrderServices $orderService */
|
||||
$orderService = app()->make(StoreOrderServices::class);
|
||||
$data['pay_price'] = $orderService->sum(['paid' => 1, 'pid' => 0, 'time' => $where['time'], 'supplier_id' => $supplier_id], 'pay_price', true);
|
||||
$data['pay_count'] = $orderService->count(['paid' => 1, 'pid' => 0, 'time' => $where['time'], 'supplier_id' => $supplier_id]);
|
||||
$times = explode('-', $where['time']);
|
||||
if(count($times) > 1){
|
||||
$times = [
|
||||
'start_time'=>$times[0],
|
||||
'end_time'=>$times[1] . ' 23:59:59'
|
||||
];
|
||||
}
|
||||
$data['refund_price'] = app()->make(StoreOrderRefundServices::class)->sum(['refund_type' => 6, 'time' => explode('-', $where['time'])],'refund_price', true);
|
||||
$data['refund_count'] = app()->make(StoreOrderRefundServices::class)->count(['refund_type' => 6, 'time' => explode('-', $where['time'])]);
|
||||
$data['coupon_price'] = $orderService->sum(['paid' => 1, 'pid' => 0, 'time' => $where['time'], 'supplier_id' => $supplier_id], 'coupon_price', true);
|
||||
$data['coupon_count'] = $orderService->search(['paid' => 1, 'pid' => 0, 'time' => $where['time'], 'is_coupon' => 1, 'supplier_id' => $supplier_id])->count();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单趋势
|
||||
* @param $where
|
||||
* @return array
|
||||
*/
|
||||
public function getTrend($where)
|
||||
{
|
||||
$supplier_id = $where['supplier_id'] ?? '';
|
||||
$time = explode('-', $where['time']);
|
||||
if (count($time) != 2) throw new AdminException('参数错误');
|
||||
$dayCount = (strtotime($time[1]) - strtotime($time[0])) / 86400 + 1;
|
||||
$data = [];
|
||||
if ($dayCount == 1) {
|
||||
$data = $this->trend($time, 0, false, $supplier_id);
|
||||
} elseif ($dayCount > 1 && $dayCount <= 31) {
|
||||
$data = $this->trend($time, 1, false, $supplier_id);
|
||||
} elseif ($dayCount > 31 && $dayCount <= 92) {
|
||||
$data = $this->trend($time, 3, false, $supplier_id);
|
||||
} elseif ($dayCount > 92) {
|
||||
$data = $this->trend($time, 30, false . $supplier_id);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单趋势
|
||||
* @param $time
|
||||
* @param $num
|
||||
* @param false $excel
|
||||
* @return array
|
||||
*/
|
||||
public function trend($time, $num, $excel = false, $supplier_id = '')
|
||||
{
|
||||
/** @var StoreOrderServices $storeOrder */
|
||||
$storeOrder = app()->make(StoreOrderServices::class);
|
||||
|
||||
if ($num == 0) {
|
||||
$xAxis = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'];
|
||||
$timeType = '%H';
|
||||
} elseif ($num != 0) {
|
||||
$dt_start = strtotime($time[0]);
|
||||
$dt_end = strtotime($time[1]);
|
||||
while ($dt_start <= $dt_end) {
|
||||
if ($num == 30) {
|
||||
$xAxis[] = date('Y-m', $dt_start);
|
||||
$dt_start = strtotime("+1 month", $dt_start);
|
||||
$timeType = '%Y-%m';
|
||||
} else {
|
||||
$xAxis[] = date('Y-m-d', $dt_start);
|
||||
$dt_start = strtotime("+$num day", $dt_start);
|
||||
$timeType = '%Y-%m-%d';
|
||||
}
|
||||
}
|
||||
}
|
||||
$pay_price = array_column($storeOrder->getProductTrend($time, $timeType, 'add_time', 'sum(pay_price)', 'pay', $supplier_id), 'num', 'days');
|
||||
$pay_count = array_column($storeOrder->getProductTrend($time, $timeType, 'add_time', 'count(id)', 'pay', $supplier_id), 'num', 'days');
|
||||
$refund_price = array_column($storeOrder->getProductTrend($time, $timeType, 'refund_reason_time', 'sum(pay_price)', 'refund', $supplier_id), 'num', 'days');
|
||||
$refund_count = array_column($storeOrder->getProductTrend($time, $timeType, 'refund_reason_time', 'count(id)', 'refund', $supplier_id), 'num', 'days');
|
||||
$coupon_price = array_column($storeOrder->getProductTrend($time, $timeType, 'add_time', 'sum(coupon_price)', 'coupon', $supplier_id), 'num', 'days');
|
||||
$coupon_count = array_column($storeOrder->getProductTrend($time, $timeType, 'add_time', 'count(id)', 'coupon', $supplier_id), 'num', 'days');
|
||||
$data = $series = [];
|
||||
foreach ($xAxis as $item) {
|
||||
$data['订单金额'][] = isset($pay_price[$item]) ? floatval($pay_price[$item]) : 0;
|
||||
$data['订单量'][] = isset($pay_count[$item]) ? floatval($pay_count[$item]) : 0;
|
||||
$data['退款金额'][] = isset($refund_price[$item]) ? floatval($refund_price[$item]) : 0;
|
||||
$data['退款订单量'][] = isset($refund_count[$item]) ? floatval($refund_count[$item]) : 0;
|
||||
$data['用券金额'][] = isset($coupon_price[$item]) ? floatval($coupon_price[$item]) : 0;
|
||||
$data['用券数量'][] = isset($coupon_count[$item]) ? floatval($coupon_count[$item]) : 0;
|
||||
}
|
||||
foreach ($data as $key => $item) {
|
||||
$series[] = [
|
||||
'name' => $key,
|
||||
'data' => $item,
|
||||
'type' => 'line',
|
||||
];
|
||||
}
|
||||
return compact('xAxis', 'series');
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单来源
|
||||
* @param $where
|
||||
* @return array
|
||||
*/
|
||||
public function getChannel($where)
|
||||
{
|
||||
$supplier_id = $where['supplier_id'] ?? '';
|
||||
/** @var StoreOrderServices $orderService */
|
||||
$orderService = app()->make(StoreOrderServices::class);
|
||||
|
||||
$bing_xdata = ['公众号', '小程序', 'H5', 'PC', 'APP'];
|
||||
$color = ['#64a1f4', '#3edeb5', '#70869f', '#ffc653', '#fc7d6a'];
|
||||
$bing_data = [];
|
||||
foreach ($bing_xdata as $key => $item) {
|
||||
$bing_data[] = [
|
||||
'name' => $item,
|
||||
'value' => $orderService->count(['paid' => 1, 'pid' => 0, 'is_channel' => $key, 'time' => $where['time'], 'supplier_id' => $supplier_id]),
|
||||
'itemStyle' => ['color' => $color[$key]]
|
||||
];
|
||||
}
|
||||
|
||||
$list = [];
|
||||
$count = array_sum(array_column($bing_data, 'value'));
|
||||
foreach ($bing_data as $key => $item) {
|
||||
$list[] = [
|
||||
'name' => $item['name'],
|
||||
'value' => $item['value'],
|
||||
'percent' => $count != 0 ? bcmul((string)bcdiv((string)$item['value'], (string)$count, 4), '100', 2) : 0,
|
||||
];
|
||||
}
|
||||
array_multisort(array_column($list, 'value'), SORT_DESC, $list);
|
||||
return compact('bing_xdata', 'bing_data', 'list');
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单类型
|
||||
* @param $where
|
||||
* @return array
|
||||
*/
|
||||
public function getType($where)
|
||||
{
|
||||
$supplier_id = $where['supplier_id'] ?? '';
|
||||
/** @var StoreOrderServices $orderService */
|
||||
$orderService = app()->make(StoreOrderServices::class);
|
||||
|
||||
$bing_xdata = ['普通订单', '秒杀订单', '砍价订单', '拼团订单', '积分订单', '套餐订单', '预售订单', '新人订单', '抽奖订单'];
|
||||
$color = ['#64a1f4', '#3edeb5', '#70869f', '#ffc653', '#ffc653', '#fc7d6a', '#b37feb', '#ff85c0', '#6dd230'];
|
||||
$bing_data = [];
|
||||
foreach ($bing_xdata as $key => $item) {
|
||||
$keys = $key;
|
||||
$bing_data[] = [
|
||||
'name' => $item,
|
||||
'value' => $orderService->together(['paid' => 1, 'pid' => 0, 'type' => $keys, 'time' => $where['time'], 'supplier_id' => $supplier_id], 'pay_price', 'sum'),
|
||||
'itemStyle' => ['color' => $color[$key]]
|
||||
];
|
||||
}
|
||||
|
||||
$list = [];
|
||||
$count = array_sum(array_column($bing_data, 'value'));
|
||||
foreach ($bing_data as $key => $item) {
|
||||
$list[] = [
|
||||
'name' => $item['name'],
|
||||
'value' => $item['value'],
|
||||
'percent' => $count != 0 ? bcmul((string)bcdiv((string)$item['value'], (string)$count, 4), '100', 2) : 0,
|
||||
];
|
||||
}
|
||||
array_multisort(array_column($list, 'value'), SORT_DESC, $list);
|
||||
return compact('bing_xdata', 'bing_data', 'list');
|
||||
}
|
||||
}
|
||||
249
app/services/statistic/ProductStatisticServices.php
Normal file
249
app/services/statistic/ProductStatisticServices.php
Normal file
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\services\statistic;
|
||||
|
||||
|
||||
use app\services\BaseServices;
|
||||
use app\services\order\StoreOrderRefundServices;
|
||||
use app\services\other\export\ExportServices;
|
||||
use app\services\order\StoreCartServices;
|
||||
use app\services\order\StoreOrderServices;
|
||||
use app\services\product\product\StoreProductLogServices;
|
||||
use app\services\product\product\StoreVisitServices;
|
||||
use crmeb\exceptions\AdminException;
|
||||
|
||||
/**
|
||||
* Class ProductStatisticServices
|
||||
* @package app\services\statistic
|
||||
*/
|
||||
class ProductStatisticServices extends BaseServices
|
||||
{
|
||||
/**
|
||||
* 商品基础
|
||||
* @param $where
|
||||
* @return array
|
||||
*/
|
||||
public function getBasic($where)
|
||||
{
|
||||
$time = explode('-', $where['time']);
|
||||
if (count($time) != 2) throw new AdminException('参数错误');
|
||||
//当前数据
|
||||
$now = $this->basicInfo($where, $time);
|
||||
//环比数据
|
||||
$dayNum = (strtotime($time[1]) - strtotime($time[0])) / 86400 + 1;
|
||||
$lastTime = array(
|
||||
date("Y/m/d", strtotime("-$dayNum days", strtotime($time[0]))),
|
||||
date("Y/m/d", strtotime("-1 days", strtotime($time[0])))
|
||||
);
|
||||
$where['time'] = implode('-', $lastTime);
|
||||
$last = $this->basicInfo($where, $lastTime);
|
||||
|
||||
//组合数据,计算环比
|
||||
$data = [];
|
||||
foreach ($now as $key => $item) {
|
||||
$data[$key]['num'] = $item;
|
||||
$num = $last[$key] > 0 ? $last[$key] : 1;
|
||||
$data[$key]['percent'] = bcmul((string)bcdiv((string)($item - $last[$key]), (string)$num, 4), 100, 2);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品基础数据
|
||||
* @param $where
|
||||
* @param $time
|
||||
* @return mixed
|
||||
*/
|
||||
public function basicInfo($where, $time)
|
||||
{
|
||||
/** @var StoreVisitServices $storeVisit */
|
||||
$storeVisit = app()->make(StoreVisitServices::class);
|
||||
/** @var StoreCartServices $storeCart */
|
||||
$storeCart = app()->make(StoreCartServices::class);
|
||||
/** @var StoreOrderServices $storeOrder */
|
||||
$storeOrder = app()->make(StoreOrderServices::class);
|
||||
|
||||
$data['browse'] = $storeVisit->getSum($where, 'count');//商品浏览量
|
||||
$data['user'] = $storeVisit->getDistinctCount($where, 'uid');//商品访客数
|
||||
$data['cart'] = $storeCart->sum($where, 'cart_num', true);//加入购物车件数
|
||||
$data['order'] = $storeOrder->sum($where + ['pid' => 0], 'total_num', true);//下单件数
|
||||
$startTime = strtotime($time[0]);
|
||||
$endTime = strtotime($time[1]);
|
||||
$order_where = [
|
||||
['pid', '=', 0],
|
||||
['paid', '=', 1],
|
||||
['pay_time', '>=', $startTime],
|
||||
['pay_time', '<', $endTime]
|
||||
];
|
||||
$data['pay'] = $storeOrder->sum($order_where, 'total_num');//支付件数
|
||||
$data['payPrice'] = $storeOrder->sum($order_where, 'pay_price');//支付金额
|
||||
$data['cost'] = $storeOrder->sum($order_where, 'cost');//成本金额
|
||||
/** @var StoreOrderRefundServices $storeOrderRefundServices */
|
||||
$storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
|
||||
$refund_where = ['is_cancel' => 0, ['refund_type' => [6]], 'time' => [$startTime, $endTime]];
|
||||
$data['refundPrice'] = $storeOrderRefundServices->sum($refund_where, 'refunded_price', true);//退款金额
|
||||
$data['refund'] = $storeOrderRefundServices->sum($refund_where, 'refund_num', true);//退款件数
|
||||
$payPeople = $storeOrder->getDistinctCount($where + ['pid' => 0, 'paid' => 1], 'uid');//成交用户数
|
||||
$data['payPercent'] = $data['user'] > 0 ? bcmul(bcdiv($payPeople, $data['user'], 4), 100, 2) : 0;//访问-付款转化率
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品趋势
|
||||
* @param $where
|
||||
* @param $excel
|
||||
* @return array
|
||||
*/
|
||||
public function getTrend($where, $excel = false)
|
||||
{
|
||||
$time = explode('-', $where['time']);
|
||||
if (count($time) != 2) throw new AdminException('参数错误');
|
||||
$dayCount = (strtotime($time[1]) - strtotime($time[0])) / 86400 + 1;
|
||||
$data = [];
|
||||
if ($dayCount == 1) {
|
||||
$data = $this->trend($time, 0, $excel);
|
||||
} elseif ($dayCount > 1 && $dayCount <= 31) {
|
||||
$data = $this->trend($time, 1, $excel);
|
||||
} elseif ($dayCount > 31 && $dayCount <= 92) {
|
||||
$data = $this->trend($time, 3, $excel);
|
||||
} elseif ($dayCount > 92) {
|
||||
$data = $this->trend($time, 30, $excel);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品趋势
|
||||
* @param $time
|
||||
* @param $num
|
||||
* @param $excel
|
||||
* @return array
|
||||
*/
|
||||
public function trend($time, $num, $excel = false)
|
||||
{
|
||||
/** @var StoreVisitServices $storeVisit */
|
||||
$storeVisit = app()->make(StoreVisitServices::class);
|
||||
/** @var StoreOrderServices $storeOrder */
|
||||
$storeOrder = app()->make(StoreOrderServices::class);
|
||||
/** @var StoreCartServices $storeCart */
|
||||
$storeCart = app()->make(StoreCartServices::class);
|
||||
/** @var StoreOrderRefundServices $storeOrderRefundServices */
|
||||
$storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
|
||||
|
||||
if ($num == 0) {
|
||||
$xAxis = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'];
|
||||
$timeType = '%H';
|
||||
} elseif ($num != 0) {
|
||||
$dt_start = strtotime($time[0]);
|
||||
$dt_end = strtotime($time[1]);
|
||||
while ($dt_start <= $dt_end) {
|
||||
if ($num == 30) {
|
||||
$xAxis[] = date('Y-m', $dt_start);
|
||||
$dt_start = strtotime("+1 month", $dt_start);
|
||||
$timeType = '%Y-%m';
|
||||
} else {
|
||||
$xAxis[] = date('m-d', $dt_start);
|
||||
$dt_start = strtotime("+$num day", $dt_start);
|
||||
$timeType = '%m-%d';
|
||||
}
|
||||
}
|
||||
}
|
||||
$browse = array_column($storeVisit->getProductTrend($time, $timeType, 'sum(count)'), 'num', 'days');
|
||||
$user = array_column($storeVisit->getProductTrend($time, $timeType, 'count(distinct(uid))'), 'num', 'days');
|
||||
$pay = array_column($storeOrder->getProductTrend($time, $timeType, 'pay_time', 'sum(pay_price)'), 'num', 'days');
|
||||
$refundList = $storeOrderRefundServices->getUserRefundPriceList($time, $timeType, 'sum(refunded_price)', 'add_time');
|
||||
$refund = array_column($refundList, 'num', 'days');
|
||||
if ($excel) {
|
||||
$cart = array_column($storeCart->getProductTrend($time, $timeType, 'sum(cart_num)'), 'num', 'days');
|
||||
$order = array_column($storeOrder->getProductTrend($time, $timeType, 'add_time', 'sum(total_num)'), 'num', 'days');
|
||||
$payNum = array_column($storeOrder->getProductTrend($time, $timeType, 'pay_time', 'sum(total_num)'), 'num', 'days');
|
||||
$payCountNum = array_column($storeOrder->getProductTrend($time, $timeType, 'pay_time', 'count(distinct(uid))'), 'num', 'days');
|
||||
$cost = array_column($storeOrder->getProductTrend($time, $timeType, 'pay_time', 'sum(cost)'), 'num', 'days');
|
||||
$orderIds = array_column($refundList, 'link_ids');
|
||||
$ids = implode(',', $orderIds);
|
||||
$totalNumList = $storeOrder->column(['refund_id' => $ids], 'total_num', 'id');
|
||||
$refundNum = array_column($refundList, 'link_ids', 'days');
|
||||
foreach ($refundNum as &$i) {
|
||||
$oIds = explode(',', $i);
|
||||
$i = array_map(function ($o) use ($totalNumList) {
|
||||
if (isset($totalNumList[$o])) {
|
||||
return $totalNumList[$o];
|
||||
}
|
||||
}, $oIds);
|
||||
$i = array_sum($i);
|
||||
}
|
||||
foreach ($xAxis as &$item) {
|
||||
if (isset($user[$item]) && isset($payCountNum[$item])) {
|
||||
$changes = bcmul(bcdiv((string)$payCountNum[$item], (string)$user[$item], 4), 100, 2);
|
||||
$changes = $changes > 100 ? 100 : $changes;
|
||||
} else {
|
||||
$changes = 0;
|
||||
}
|
||||
$data[] = [
|
||||
'time' => $item,
|
||||
'browse' => $browse[$item] ?? 0,
|
||||
'user' => $user[$item] ?? 0,
|
||||
'pay' => $pay[$item] ?? 0,
|
||||
'refund' => $refund[$item] ?? 0,
|
||||
'cart' => $cart[$item] ?? 0,
|
||||
'order' => $order[$item] ?? 0,
|
||||
'payNum' => $payNum[$item] ?? 0,
|
||||
'cost' => $cost[$item] ?? 0,
|
||||
'refundNum' => $refundNum[$item] ?? 0,
|
||||
'changes' => $changes
|
||||
];
|
||||
}
|
||||
/** @var ExportServices $exportService */
|
||||
$exportService = app()->make(ExportServices::class);
|
||||
return $exportService->productTrade($data);
|
||||
} else {
|
||||
$data = $series = [];
|
||||
foreach ($xAxis as $item) {
|
||||
$data['商品浏览量'][] = isset($browse[$item]) ? floatval($browse[$item]) : 0;
|
||||
$data['商品访客量'][] = isset($user[$item]) ? floatval($user[$item]) : 0;
|
||||
$data['支付金额'][] = isset($pay[$item]) ? floatval($pay[$item]) : 0;
|
||||
$data['退款金额'][] = isset($refund[$item]) ? floatval($refund[$item]) : 0;
|
||||
}
|
||||
foreach ($data as $key => $item) {
|
||||
if ($key == '商品浏览量' || $key == '商品访客量') {
|
||||
$series[] = [
|
||||
'name' => $key,
|
||||
'data' => $item,
|
||||
'type' => 'line',
|
||||
'smooth' => 'true',
|
||||
'yAxisIndex' => 1,
|
||||
];
|
||||
} else {
|
||||
$series[] = [
|
||||
'name' => $key,
|
||||
'data' => $item,
|
||||
'type' => 'bar',
|
||||
];
|
||||
}
|
||||
}
|
||||
return compact('xAxis', 'series');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品排行
|
||||
* @param $where
|
||||
* @return mixed
|
||||
*/
|
||||
public function getProductRanking($where)
|
||||
{
|
||||
/** @var StoreProductLogServices $productLog */
|
||||
$productLog = app()->make(StoreProductLogServices::class);
|
||||
return $productLog->getRanking($where);
|
||||
}
|
||||
}
|
||||
868
app/services/statistic/TradeStatisticServices.php
Normal file
868
app/services/statistic/TradeStatisticServices.php
Normal file
@@ -0,0 +1,868 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\services\statistic;
|
||||
|
||||
use app\services\BaseServices;
|
||||
use app\services\order\StoreOrderRefundServices;
|
||||
use app\services\other\export\ExportServices;
|
||||
use app\services\order\OtherOrderServices;
|
||||
use app\services\order\StoreOrderServices;
|
||||
use app\services\user\UserExtractServices;
|
||||
use app\services\user\UserMoneyServices;
|
||||
use app\services\user\UserRechargeServices;
|
||||
|
||||
/**
|
||||
* Class TradeStatisticServices
|
||||
* @package app\services\statistic
|
||||
*/
|
||||
class TradeStatisticServices extends BaseServices
|
||||
{
|
||||
public array $_day = ['00时', '01时', '02时', '03时', '04时', '05时', '06时', '07时', '08时', '09时', '10时', '11时', '12时', '13时', '14时', '15时', '16时', '17时', '18时', '19时', '20时', '21时', '22时', '23时', '24时'];
|
||||
|
||||
/**
|
||||
* 基本概况
|
||||
* @param $where
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTopLeftTrade($where)
|
||||
{
|
||||
//总交易额
|
||||
$selectType = "sum";
|
||||
$tradeTotalMoney = $this->tradeTotalMoney($where, $selectType);
|
||||
//交易曲线
|
||||
$selectType = "group";
|
||||
$hourTotalMoney = $this->tradeGroupMoney($where, $selectType);
|
||||
return ['total_money' => $tradeTotalMoney, 'curve' => $hourTotalMoney];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取今日订单数和支付人数统计
|
||||
* @return array
|
||||
*/
|
||||
public function getTopRightOneTrade()
|
||||
{
|
||||
/** @var StoreOrderServices $orderService */
|
||||
$orderService = app()->make(StoreOrderServices::class);
|
||||
/** day订单数 */
|
||||
//今日订单数
|
||||
$orderCountWhere['is_del'] = 0;
|
||||
$orderCountWhere['paid'] = 1;
|
||||
$orderCountWhere['pid'] = 0;
|
||||
$orderCountWhere['refund_status'] = [0, 3];
|
||||
$orderCountWhere['timeKey'] = $this->TimeConvert("today");
|
||||
$todayOrderCount = $orderService->getOrderCountByWhere($orderCountWhere);
|
||||
|
||||
//今日订单数曲线
|
||||
$todayHourOrderCount = $orderService->getOrderGroupCountByWhere($orderCountWhere);
|
||||
$todayHourOrderCount = $this->trendYdata((array)$todayHourOrderCount, $orderCountWhere['timeKey']);
|
||||
//昨日订单数
|
||||
$yestodayWhere['is_del'] = 0;
|
||||
$yestodayWhere['paid'] = 1;
|
||||
$yestodayWhere['pid'] = 0;
|
||||
$yestodayWhere['refund_status'] = [0, 3];
|
||||
$yestodayWhere['timeKey'] = $this->TimeConvert("yestoday");
|
||||
$yesTodayOrderCount = $orderService->getOrderCountByWhere($yestodayWhere);
|
||||
//昨日订单曲线
|
||||
// $yestodayHourOrderCount = $orderService->getOrderGroupCountByWhere($yestodayWhere);
|
||||
// $yestodayHourOrderCount = $this->trendYdata((array)$yestodayHourOrderCount, 'day');
|
||||
//订单数环比增长率
|
||||
$orderCountDayChain = $this->countRate($todayOrderCount, $yesTodayOrderCount);
|
||||
$data[] = [
|
||||
'name' => "今日订单数",
|
||||
'now_value' => $todayOrderCount,
|
||||
'last_value' => $yesTodayOrderCount,
|
||||
'rate' => $orderCountDayChain,
|
||||
'curve' => $todayHourOrderCount
|
||||
];
|
||||
/** day支付人数 */
|
||||
//今日支付人数
|
||||
$orderPeopleWhere['timeKey'] = $this->TimeConvert("today");
|
||||
$orderPeopleWhere['paid'] = 1;
|
||||
$orderPeopleWhere['pid'] = 0;
|
||||
$todayPayOrderPeople = count($orderService->getPayOrderPeopleByWhere($orderPeopleWhere));
|
||||
//今日支付人数曲线
|
||||
$todayHourOrderPeople = $orderService->getPayOrderGroupPeopleByWhere($orderPeopleWhere);
|
||||
$todayHourOrderPeople = $this->trendYdata((array)$todayHourOrderPeople, $orderPeopleWhere['timeKey']);
|
||||
//昨日支付人数
|
||||
$yestodayOrderPeopleWhere['timeKey'] = $this->TimeConvert("yestoday");
|
||||
$yestodayOrderPeopleWhere['paid'] = 1;
|
||||
$yestodayPayOrderPeople = count($orderService->getPayOrderPeopleByWhere($yestodayOrderPeopleWhere));
|
||||
//昨日支付曲线
|
||||
// $yestodayHourOrderPeople = $orderService->getPayOrderGroupPeopleByWhere($yestodayOrderPeopleWhere);
|
||||
// $yestodayHourOrderPeople = $this->trendYdata((array)$yestodayHourOrderPeople, 'day');
|
||||
//订单支付人数环比
|
||||
$orderPeopleDayChain = $this->countRate($todayPayOrderPeople, $yestodayPayOrderPeople);
|
||||
$data[] = [
|
||||
'name' => "今日支付人数",
|
||||
'now_value' => $todayPayOrderPeople,
|
||||
'last_value' => $yestodayPayOrderPeople,
|
||||
'rate' => $orderPeopleDayChain,
|
||||
'curve' => $todayHourOrderPeople
|
||||
];
|
||||
$new_data = [];
|
||||
foreach ($data as $k => $v) {
|
||||
$new_data['x'] = $v['curve']['x'];
|
||||
$new_data['series'][$k]['name'] = $v['name'];
|
||||
$new_data['series'][$k]['now_money'] = $v['now_value'];
|
||||
$new_data['series'][$k]['last_money'] = $v['last_value'];
|
||||
$new_data['series'][$k]['rate'] = $v['rate'];
|
||||
$new_data['series'][$k]['value'] = array_values($v['curve']['y']);
|
||||
|
||||
}
|
||||
|
||||
return $new_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本月订单数和支付人数统计
|
||||
* @return array
|
||||
*/
|
||||
public function getTopRightTwoTrade()
|
||||
{
|
||||
/** @var StoreOrderServices $orderService */
|
||||
$orderService = app()->make(StoreOrderServices::class);
|
||||
/** month订单数 */
|
||||
$monthOrderCountWhere['is_del'] = 0;
|
||||
$monthOrderCountWhere['paid'] = 1;
|
||||
$monthOrderCountWhere['pid'] = 0;
|
||||
$monthOrderCountWhere['timeKey'] = $this->TimeConvert("month");
|
||||
$monthOrderCount = $orderService->getOrderCountByWhere($monthOrderCountWhere);
|
||||
//本月订单数曲线
|
||||
$monthCurveOrderCount = $orderService->getOrderGroupCountByWhere($monthOrderCountWhere);
|
||||
$monthCurveOrderCount = $this->trendYdata((array)$monthCurveOrderCount, $monthOrderCountWhere['timeKey']);
|
||||
//上月订单数
|
||||
$lastOrderCountWhere['timeKey'] = $this->TimeConvert("last_month");
|
||||
$lastOrderCountWhere['is_del'] = 0;
|
||||
$lastOrderCountWhere['paid'] = 1;
|
||||
$lastOrderCountWhere['pid'] = 0;
|
||||
$lastOrderCount = $orderService->getOrderCountByWhere($lastOrderCountWhere);
|
||||
//上月订单曲线
|
||||
// $lastCurveOrderCount = $orderService->getOrderGroupCountByWhere($lastOrderCountWhere);
|
||||
// $lastCurveOrderCount = $this->trendYdata((array)$lastCurveOrderCount, 'month');
|
||||
//订单数环比增长率
|
||||
// $orderCountMonthChain = (($monthOrderCount - $lastOrderCount) / $lastOrderCount) * 100;
|
||||
$orderCountMonthChain = $this->countRate($monthOrderCount, $lastOrderCount);
|
||||
$data[] = [
|
||||
'name' => "本月订单数",
|
||||
'now_value' => $monthOrderCount,
|
||||
'last_value' => $lastOrderCount,
|
||||
'rate' => $orderCountMonthChain,
|
||||
'curve' => $monthCurveOrderCount
|
||||
];
|
||||
/** month下单人数 */
|
||||
//本月支付人数
|
||||
$monthOrderPeopleWhere['timeKey'] = $this->TimeConvert("month");
|
||||
$monthOrderPeopleWhere['paid'] = 1;
|
||||
$monthPayOrderPeople = count($orderService->getPayOrderPeopleByWhere($monthOrderPeopleWhere));
|
||||
//本月支付人数曲线
|
||||
$monthCurveOrderPeople = $orderService->getPayOrderGroupPeopleByWhere($monthOrderPeopleWhere);
|
||||
$monthCurveOrderPeople = $this->trendYdata((array)$monthCurveOrderPeople, $monthOrderPeopleWhere['timeKey']);
|
||||
//上月支付人数
|
||||
$lastOrderPeopleWhere['timeKey'] = $this->TimeConvert("last_month");
|
||||
$lastOrderPeopleWhere['paid'] = 1;
|
||||
$lastPayOrderPeople = count($orderService->getPayOrderPeopleByWhere($lastOrderPeopleWhere));
|
||||
//上月支付曲线
|
||||
// $lastCurveOrderPeople = $orderService->getPayOrderGroupPeopleByWhere($lastOrderPeopleWhere);
|
||||
// $lastCurveOrderPeople = $this->trendYdata((array)$lastCurveOrderPeople, 'month');
|
||||
//订单支付人数环比
|
||||
$orderPeopleDayChain = $this->countRate($monthPayOrderPeople, $lastPayOrderPeople);
|
||||
$data[] = [
|
||||
'name' => "本月支付人数",
|
||||
'now_value' => $monthPayOrderPeople,
|
||||
'last_value' => $lastPayOrderPeople,
|
||||
'rate' => $orderPeopleDayChain,
|
||||
'curve' => $monthCurveOrderPeople
|
||||
];
|
||||
$new_data = [];
|
||||
foreach ($data as $k => $v) {
|
||||
$new_data[$k]['name'] = $v['name'];
|
||||
$new_data[$k]['now_money'] = $v['now_value'];
|
||||
$new_data[$k]['last_money'] = $v['last_value'];
|
||||
$new_data[$k]['rate'] = $v['rate'];
|
||||
$new_data[$k]['value'] = $v['curve']['y'];
|
||||
}
|
||||
|
||||
return $new_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 交易总额
|
||||
* @param $where
|
||||
* @param $selectType
|
||||
* @return array|float|int|mixed
|
||||
*/
|
||||
public function tradeTotalMoney($where, $selectType, $isNum = false)
|
||||
{
|
||||
/** 收入营业额 */
|
||||
//商品订单收入
|
||||
$inOrderMoney = $this->getOrderTotalMoney($where, $selectType, "", $isNum);
|
||||
//用户充值收入
|
||||
$inRechargeMoneyHome = $this->getRechargeTotalMoney($where, $selectType, "", $isNum);
|
||||
$inrechgeMoneyAdmin = $this->getBillYeTotalMoney($where, $selectType, '', $isNum);
|
||||
$inRechargeMoney = bcadd($inRechargeMoneyHome, $inrechgeMoneyAdmin, 2);
|
||||
//购买会员收入
|
||||
$inMemberMoney = $this->getMemberTotalMoney($where, $selectType, "", $isNum);
|
||||
//线下收款收入
|
||||
$inOfflineMoney = $this->getOfflineTotalMoney($where, $selectType, "", $isNum);
|
||||
//总交易额
|
||||
$inTotalMoney = bcadd(bcadd($inOrderMoney, $inRechargeMoney, 2), bcadd($inMemberMoney, $inOfflineMoney, 2), 2);/* - $outExtractUserMoney*/
|
||||
return $inTotalMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* 交易额曲线图
|
||||
* @param $where
|
||||
* @param $selectType
|
||||
* @return array
|
||||
*/
|
||||
public function tradeGroupMoney($where, $selectType)
|
||||
{
|
||||
|
||||
//商品订单收入
|
||||
$orderGroup = "add_time";
|
||||
$OrderMoney = $this->getOrderTotalMoney($where, $selectType, $orderGroup);
|
||||
//用户充值收入
|
||||
$rechargeGroup = "add_time";
|
||||
$RechargeMoneyHome = $this->getRechargeTotalMoney($where, $selectType, $rechargeGroup);
|
||||
$RechargeMoneyAdmin = $this->getBillYeTotalMoney($where, $selectType, $rechargeGroup);
|
||||
$RechargeMoney = $this->totalArrData([$RechargeMoneyHome, $RechargeMoneyAdmin]);
|
||||
//购买会员收入
|
||||
$memberGroup = "add_time";
|
||||
$MemberMoney = $this->getMemberTotalMoney($where, $selectType, $memberGroup);
|
||||
//线下收款收入
|
||||
$offlineGroup = "add_time";
|
||||
$OfflineMoney = $this->getOfflineTotalMoney($where, $selectType, $offlineGroup);
|
||||
return $this->totalArrData([$OrderMoney, $RechargeMoney, $MemberMoney, $OfflineMoney]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 底部数据
|
||||
* @param $where
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getBottomTrade($where)
|
||||
{
|
||||
|
||||
if (!$where['data']) {
|
||||
$where['time'] = ['start_time' => date('Y-m-d 00:00:00', time()), "end_time" => date('Y-m-d 23:59:59', time())];
|
||||
} else {
|
||||
$time = explode("-", $where['data']);
|
||||
$where['time'] = ['start_time' => date('Y-m-d 00:00:00', strtotime($time[0])), "end_time" => date('Y-m-d 23:59:59', strtotime($time[1]))];
|
||||
}
|
||||
unset($where['data']);
|
||||
/** @var ExportServices $exportService */
|
||||
$exportService = app()->make(ExportServices::class);
|
||||
$chainTime = $this->chainTime($where['time']);
|
||||
$isNum = false;
|
||||
if ($chainTime == "other") $isNum = true;
|
||||
$dateWhere['time'] = $isNum ? $where['time'] : $chainTime;
|
||||
$topData = array();
|
||||
$Chain = array();
|
||||
|
||||
/** 商品支付金额 */
|
||||
$OrderMoney = $this->getOrderTotalMoney($where, "sum");
|
||||
$lastOrderMoney = $this->getOrderTotalMoney($dateWhere, "sum", "", $isNum);
|
||||
$OrderCurve = $this->getOrderTotalMoney($where, "group", "add_time");
|
||||
$OrderChain = $this->countRate($OrderMoney, $lastOrderMoney);
|
||||
$topData[2] = [
|
||||
'title' => '商品支付金额',
|
||||
'desc' => '选定条件下,用户购买商品的实际支付金额,包括微信支付、余额支付、支付宝支付、线下支付金额(拼团商品在成团之后计入,线下支付订单在后台确认支付后计入)',
|
||||
'total_money' => $OrderMoney,
|
||||
'rate' => $OrderChain,
|
||||
'value' => $OrderCurve['y'],
|
||||
'type' => 1,
|
||||
'sign' => 'goods',
|
||||
];
|
||||
|
||||
$Chain['goods'] = $OrderCurve;
|
||||
|
||||
/** 购买会员金额 */
|
||||
$memberMoney = $this->getMemberTotalMoney($where, 'sum');
|
||||
$lastMemberMoney = $this->getMemberTotalMoney($dateWhere, 'sum', "", $isNum);
|
||||
$memberCurve = $this->getMemberTotalMoney($where, 'group', "pay_time");
|
||||
$MemberChain = $this->countRate($memberMoney, $lastMemberMoney);
|
||||
$topData[3] = [
|
||||
'title' => '购买会员金额',
|
||||
'desc' => '选定条件下,用户成功购买付费会员的金额',
|
||||
'total_money' => $memberMoney,
|
||||
'rate' => $MemberChain,
|
||||
'value' => $memberCurve['y'],
|
||||
'type' => 1,
|
||||
'sign' => 'member',
|
||||
];
|
||||
$Chain['member'] = $memberCurve;
|
||||
|
||||
/** 充值金额 */
|
||||
$rechgeMoneyHome = $this->getRechargeTotalMoney($where, 'sum');
|
||||
$rechgeMoneyAdmin = $this->getBillYeTotalMoney($where, 'sum');
|
||||
$rechgeMoneyTotal = bcadd($rechgeMoneyHome, $rechgeMoneyAdmin, 2);
|
||||
$lastRechgeMoneyHome = $this->getRechargeTotalMoney($dateWhere, 'sum', "", $isNum);
|
||||
$lastRechgeMoneyAdmin = $this->getBillYeTotalMoney($dateWhere, 'sum', "", $isNum);
|
||||
$lastRechgeMoneyTotal = bcadd($lastRechgeMoneyHome, $lastRechgeMoneyAdmin, 2);
|
||||
$RechgeHomeCurve = $this->getRechargeTotalMoney($where, 'group', "pay_time");
|
||||
$RechgeAdminCurve = $this->getBillYeTotalMoney($where, 'group', "add_time");
|
||||
$RechgeTotalCurve = $this->totalArrData([$RechgeHomeCurve, $RechgeAdminCurve]);
|
||||
$RechgeChain = $this->countRate($rechgeMoneyTotal, $lastRechgeMoneyTotal);
|
||||
$topData[4] = [
|
||||
'title' => '充值金额',
|
||||
'desc' => '选定条件下,用户成功充值的金额',
|
||||
'total_money' => $rechgeMoneyTotal,
|
||||
'rate' => $RechgeChain,
|
||||
'value' => $RechgeTotalCurve['y'],
|
||||
'type' => 1,
|
||||
'sign' => 'rechge',
|
||||
];
|
||||
$Chain['rechage'] = $RechgeTotalCurve;
|
||||
|
||||
/** 线下收银 */
|
||||
$offlineMoney = $this->getOfflineTotalMoney($where, 'sum');
|
||||
$lastOfflineMoney = $this->getOfflineTotalMoney($dateWhere, 'sum', "", $isNum);
|
||||
$offlineCurve = $this->getOfflineTotalMoney($where, 'group', "pay_time");
|
||||
$offlineChain = $this->countRate($offlineMoney, $lastOfflineMoney);
|
||||
$topData[5] = [
|
||||
'title' => '线下收银金额',
|
||||
'desc' => '选定条件下,用户在线下扫码支付的金额',
|
||||
'total_money' => $offlineMoney,
|
||||
'rate' => $offlineChain,
|
||||
'value' => $offlineCurve['y'],
|
||||
'type' => 0,
|
||||
'sign' => 'offline',
|
||||
];
|
||||
$Chain['offline'] = $offlineCurve;
|
||||
|
||||
/** 支出*/
|
||||
//余额支付商品
|
||||
$outYeOrderMoney = $this->getOrderTotalMoney(['pay_type' => "yue", 'time' => $where['time']], 'sum');
|
||||
$lastOutYeOrderMoney = $this->getOrderTotalMoney(['pay_type' => "yue", 'time' => $dateWhere['time']], 'sum', "", $isNum);
|
||||
$outYeOrderCurve = $this->getOrderTotalMoney(['pay_type' => "yue", 'time' => $where['time']], 'group', 'pay_time');
|
||||
$outYeOrderChain = $this->countRate($outYeOrderMoney, $lastOutYeOrderMoney);
|
||||
//余额购买会员
|
||||
$outYeMemberMoney = $this->getMemberTotalMoney(['pay_type' => "yue", 'time' => $where['time']], 'sum');
|
||||
$lastOutYeMemberMoney = $this->getMemberTotalMoney(['pay_type' => "yue", 'time' => $dateWhere['time']], 'sum', "", $isNum);
|
||||
$outYeMemberCurve = $this->getMemberTotalMoney(['pay_type' => "yue", 'time' => $where['time']], 'group', "pay_time");
|
||||
$outYeMemberChain = $this->countRate($outYeMemberMoney, $lastOutYeMemberMoney);
|
||||
//余额支付
|
||||
$outYeMoney = bcadd($outYeOrderMoney, $outYeMemberMoney, 2);
|
||||
$lastOutYeMoney = bcadd($lastOutYeOrderMoney, $lastOutYeMemberMoney, 2);
|
||||
$outYeCurve = $this->totalArrData([$outYeOrderCurve, $outYeMemberCurve]);
|
||||
$outYeChain = $this->countRate($outYeOrderChain, $outYeMemberChain);
|
||||
$topData[7] = [
|
||||
'title' => '余额支付金额',
|
||||
'desc' => '用户下单时使用余额实际支付的金额',
|
||||
'total_money' => $outYeMoney,
|
||||
'rate' => $outYeChain,
|
||||
'value' => $outYeCurve['y'],
|
||||
'type' => 0,
|
||||
'sign' => 'yue',
|
||||
];
|
||||
$Chain['out_ye'] = $outYeCurve;
|
||||
|
||||
|
||||
//支付佣金金额
|
||||
$outExtractMoney = $this->getExtractTotalMoney($where, 'sum');
|
||||
$lastOutExtractMoney = $this->getExtractTotalMoney($dateWhere, 'sum', "", $isNum);
|
||||
$OutExtractCurve = $this->getExtractTotalMoney($where, 'group', "add_time");
|
||||
$OutExtractChain = $this->countRate($outExtractMoney, $lastOutExtractMoney);
|
||||
$topData[8] = [
|
||||
'title' => '支付佣金金额',
|
||||
'desc' => '后台给推广员支付的推广佣金,以实际支付为准',
|
||||
'total_money' => $outExtractMoney,
|
||||
'rate' => $OutExtractChain,
|
||||
'value' => $OutExtractCurve['y'],
|
||||
'type' => 0,
|
||||
'sign' => 'yong',
|
||||
];
|
||||
$Chain['extract'] = $OutExtractCurve;
|
||||
//商品退款金额
|
||||
$outOrderRefund = $this->getOrderRefundTotalMoney(['refund_type' => 6, 'time' => $where['time']], 'sum');
|
||||
$lastOutOrderRefund = $this->getOrderRefundTotalMoney(['refund_type' => 6, 'time' => $dateWhere['time']], 'sum', "", $isNum);
|
||||
$outOrderRefundCurve = $this->getOrderRefundTotalMoney(['refund_type' => 6, 'time' => $where['time']], 'group', 'add_time');
|
||||
$orderRefundChain = $this->countRate($outOrderRefund, $lastOutOrderRefund);
|
||||
$topData[9] = [
|
||||
'title' => '商品退款金额',
|
||||
'desc' => '用户成功退款的商品金额',
|
||||
'total_money' => $outOrderRefund,
|
||||
'rate' => $orderRefundChain,
|
||||
'value' => $outOrderRefundCurve['y'],
|
||||
'type' => 0,
|
||||
'sign' => 'refund',
|
||||
];
|
||||
$Chain['refund'] = $outOrderRefundCurve;
|
||||
|
||||
//支出金额
|
||||
$outTotalMoney = bcadd(bcadd($outYeMoney, $outExtractMoney, 2), $outOrderRefund, 2);
|
||||
$lastOutTotalMoney = bcadd(bcadd($lastOutYeMoney, $lastOutExtractMoney, 2), $lastOutOrderRefund, 2);
|
||||
$outTotalCurve = $this->totalArrData([$outYeCurve, $OutExtractCurve, $outOrderRefundCurve]);
|
||||
$outTotalChain = $this->countRate($outTotalMoney, $lastOutTotalMoney);
|
||||
$topData[6] = [
|
||||
'title' => '支出金额',
|
||||
'desc' => '余额支付金额、支付佣金金额、商品退款金额',
|
||||
'total_money' => $outTotalMoney,
|
||||
'rate' => $outTotalChain,
|
||||
'value' => $outTotalCurve['y'],
|
||||
'type' => 1,
|
||||
'sign' => 'out',
|
||||
];
|
||||
$Chain['out'] = $outTotalCurve;
|
||||
|
||||
/** 交易毛利金额*/
|
||||
$jiaoyiMoney = $this->tradeTotalMoney($where, "sum");
|
||||
|
||||
$jiaoyiMoney = bcsub($jiaoyiMoney, $outTotalMoney, 2);
|
||||
$lastJiaoyiMoney = $this->tradeTotalMoney($dateWhere, "sum", $isNum);
|
||||
$lastJiaoyiMoney = bcsub($lastJiaoyiMoney, $lastOutTotalMoney, 2);
|
||||
$jiaoyiCurve = $this->tradeGroupMoney($where, "group");
|
||||
$jiaoyiCurve = $this->subdutionArrData($jiaoyiCurve, $outTotalCurve);
|
||||
$jiaoyiChain = $this->countRate($jiaoyiMoney, $lastJiaoyiMoney);
|
||||
$topData[1] = [
|
||||
'title' => '交易毛利金额',
|
||||
'desc' => '交易毛利金额 = 营业额 - 支出金额',
|
||||
'total_money' => $jiaoyiMoney,
|
||||
'rate' => $jiaoyiChain,
|
||||
'value' => $jiaoyiCurve['y'],
|
||||
'type' => 1,
|
||||
'sign' => 'jiaoyi',
|
||||
];
|
||||
$Chain['jiaoyi'] = $jiaoyiCurve;
|
||||
|
||||
/** @var 营业额 $inTotalMoney */
|
||||
$inTotalMoney = $this->tradeTotalMoney($where, "sum");
|
||||
$lastInTotalMoney = $this->tradeTotalMoney($dateWhere, "sum", $isNum);
|
||||
$inTotalCurve = $this->tradeGroupMoney($where, "group");
|
||||
$inTotalChain = $this->countRate($inTotalMoney, $lastInTotalMoney);
|
||||
$topData[0] = [
|
||||
'title' => '营业额',
|
||||
'desc' => '商品支付金额、充值金额、购买付费会员金额、线下收银金额',
|
||||
'total_money' => $inTotalMoney,
|
||||
'rate' => $inTotalChain,
|
||||
'value' => $inTotalCurve['y'],
|
||||
'type' => 1,
|
||||
'sign' => 'in',
|
||||
];
|
||||
ksort($topData);
|
||||
$data = [];
|
||||
foreach ($topData as $k => $v) {
|
||||
$data['x'] = $Chain['out']['x'];
|
||||
$data['series'][$k]['name'] = $v['title'];
|
||||
$data['series'][$k]['desc'] = $v['desc'];
|
||||
$data['series'][$k]['money'] = $v['total_money'];
|
||||
$data['series'][$k]['type'] = $v['type'];
|
||||
$data['series'][$k]['rate'] = $v['rate'];
|
||||
$data['series'][$k]['value'] = array_values($v['value']);
|
||||
}
|
||||
$export = $exportService->tradeData($data, '交易统计', 2);
|
||||
$data['export'] = $export[0];
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 多个数组相加
|
||||
* @param array $arr
|
||||
* @return array|false
|
||||
*/
|
||||
public function totalArrData(array $arr)
|
||||
{
|
||||
if (!$arr || !is_array($arr)) return false;
|
||||
$item = array();
|
||||
$y = array_column($arr, "y");
|
||||
$x = array_column($arr, "x")[0];
|
||||
foreach ($y as $key => $value) {
|
||||
foreach ($value as $k => $v) {
|
||||
if (isset($item[$k])) {
|
||||
$item[$k] = bcadd($item[$k], $v, 2);
|
||||
} else {
|
||||
$item[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ['x' => $x, 'y' => $item];
|
||||
}
|
||||
|
||||
/**
|
||||
* 数组相减
|
||||
* @param array $arr1
|
||||
* @param array $arr2
|
||||
* @return array
|
||||
*/
|
||||
public function subdutionArrData(array $arr1, array $arr2)
|
||||
{
|
||||
$item = array();
|
||||
foreach ($arr1['y'] as $key => $value) {
|
||||
$item['y'][$key] = bcsub($value, $arr2['y'][$key], 2);
|
||||
}
|
||||
$item['x'] = $arr1['x'];
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索时间转换
|
||||
* @param $timeKey
|
||||
* @param false $isNum
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function TimeConvert($timeKey, $isNum = false)
|
||||
{
|
||||
switch ($timeKey) {
|
||||
case "today" :
|
||||
$data['start_time'] = date('Y-m-d 00:00:00', time());
|
||||
$data['end_time'] = date('Y-m-d 23:59:59', time());
|
||||
$data['days'] = 1;
|
||||
break;
|
||||
case "yestoday" :
|
||||
$data['start_time'] = date('Y-m-d 00:00:00', strtotime('-1 day'));
|
||||
$data['end_time'] = date('Y-m-d 23:59:59', strtotime('-1 day'));
|
||||
$data['days'] = 1;
|
||||
break;
|
||||
case "last_month" :
|
||||
$data['start_time'] = date('Y-m-01 00:00:00', strtotime('-1 month'));
|
||||
$data['end_time'] = date('Y-m-t 23:59:59', strtotime('-1 month'));
|
||||
$data['days'] = 30;
|
||||
break;
|
||||
case "month" :
|
||||
$data['start_time'] = $month_start_time = date('Y-m-01 00:00:00', strtotime(date("Y-m-d")));
|
||||
$data['end_time'] = date('Y-m-d 23:59:59', strtotime("$month_start_time +1 month -1 day"));
|
||||
$data['days'] = 30;
|
||||
break;
|
||||
case "year" :
|
||||
$data['start_time'] = date('Y-01-01 00:00:00', time());
|
||||
$data['end_time'] = date('Y-12-t 23:59:59', time());
|
||||
$data['days'] = 365;
|
||||
break;
|
||||
case "last_year" :
|
||||
$data['start_time'] = date('Y-01-01 00:00:00', strtotime('-1 year'));
|
||||
$data['end_time'] = date('Y-12-t 23:59:59', strtotime('-1 year'));
|
||||
$data['days'] = 365;
|
||||
break;
|
||||
case 30 :
|
||||
case 15 :
|
||||
case 7 :
|
||||
if (!$isNum) {
|
||||
$data['start_time'] = date("Y-m-d 00:00:00", strtotime("-$timeKey day"));
|
||||
$data['end_time'] = date('Y-m-d 23:59:59', time());
|
||||
$data['days'] = $timeKey;
|
||||
} else {
|
||||
$day = $timeKey * 2;
|
||||
$data['start_time'] = date("Y-m-d 00:00:00", strtotime("-$day day"));
|
||||
$data['end_time'] = date("Y-m-d 23:59:59", strtotime("-$timeKey day"));
|
||||
$data['days'] = $timeKey;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$datetime_start = new \DateTime($timeKey['start_time']);
|
||||
$datetime_end = new \DateTime($timeKey['end_time']);
|
||||
$days = $datetime_start->diff($datetime_end)->days;
|
||||
$days = $days > 0 ? $days : 1;
|
||||
if (!$isNum) {
|
||||
$data['start_time'] = $timeKey['start_time'];
|
||||
$data['end_time'] = $timeKey['end_time'];
|
||||
$data['days'] = $days;
|
||||
} else {
|
||||
$data['start_time'] = date("Y-m-d 00:00:00", strtotime("-$days day"));
|
||||
$data['end_time'] = $timeKey['start_time'];
|
||||
$data['days'] = $days;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单退款
|
||||
* @param $where
|
||||
* @param string $selectType
|
||||
* @param string $group
|
||||
* @param bool $isNum
|
||||
* @return array|float|int
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getOrderRefundTotalMoney($where, string $selectType, string $group = '', bool $isNum = false)
|
||||
{
|
||||
$orderSumField = isset($where['refund_type']) ? "refunded_price" : "refund_price";
|
||||
$whereOrderMoner['refund_type'] = isset($where['refund_type']) ? $where['refund_type'] : 6;
|
||||
$whereOrderMoner['is_cancel'] = 0;
|
||||
$whereOrderMoner['timeKey'] = $this->TimeConvert($where['time'], $isNum);
|
||||
|
||||
$storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
|
||||
$totalMoney = $storeOrderRefundServices->getOrderRefundMoneyByWhere($whereOrderMoner, $orderSumField, $selectType, $group);
|
||||
|
||||
if ($group) {
|
||||
$totalMoney = $this->trendYdata((array)$totalMoney, $whereOrderMoner['timeKey']);
|
||||
}
|
||||
return $totalMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品营收
|
||||
* @param $where
|
||||
* @param string $selectType
|
||||
* @param string $group
|
||||
* @param bool $isNum
|
||||
* @return array|float|int
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getOrderTotalMoney($where, string $selectType, string $group = "", bool $isNum = false)
|
||||
{
|
||||
/** 普通商品订单支付金额 */
|
||||
/** @var StoreOrderServices $storeOrderService */
|
||||
$storeOrderService = app()->make(StoreOrderServices::class);
|
||||
$orderSumField = isset($where['refund_status']) ? "refund_price" : "pay_price";
|
||||
$whereOrderMoner['refund_status'] = isset($where['refund_status']) ? $where['refund_status'] : 0;
|
||||
$whereOrderMoner['is_del'] = 0;
|
||||
$whereOrderMoner['paid'] = 1;
|
||||
$whereOrderMoner['pid'] = 0;
|
||||
|
||||
if (isset($where['pay_type'])) {
|
||||
$whereOrderMoner['pay_type'] = $where['pay_type'];
|
||||
} else {
|
||||
// $whereOrderMoner['pay_type_no'] = 2;
|
||||
}
|
||||
$whereOrderMoner['timeKey'] = $this->TimeConvert($where['time'], $isNum);
|
||||
$totalMoney = $storeOrderService->getOrderMoneyByWhere($whereOrderMoner, $orderSumField, $selectType, $group);
|
||||
|
||||
if ($group) {
|
||||
$totalMoney = $this->trendYdata((array)$totalMoney, $whereOrderMoner['timeKey']);
|
||||
}
|
||||
return $totalMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付佣金
|
||||
* @param $where
|
||||
* @param string $selectType
|
||||
* @param string $group
|
||||
* @param bool $isNum
|
||||
* @return array|float|mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getExtractTotalMoney($where, string $selectType, string $group = "", bool $isNum = false)
|
||||
{
|
||||
/** 普通商品订单支付金额 */
|
||||
/** @var UserExtractServices $extractService */
|
||||
$extractService = app()->make(UserExtractServices::class);
|
||||
$orderSumField = "extract_price";
|
||||
$whereData['status'] = 1;
|
||||
$whereData['timeKey'] = $this->TimeConvert($where['time'], $isNum);
|
||||
$totalMoney = $extractService->getOutMoneyByWhere($whereData, $orderSumField, $selectType, $group);
|
||||
if ($group) {
|
||||
|
||||
$totalMoney = $this->trendYdata((array)$totalMoney, $whereData['timeKey']);
|
||||
|
||||
}
|
||||
return $totalMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户充值营收
|
||||
* @param array $where
|
||||
* @param string $selectType
|
||||
* @param string $group
|
||||
* @param bool $isNum
|
||||
* @return array|float|int
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getRechargeTotalMoney(array $where, string $selectType, string $group = "", bool $isNum = false)
|
||||
{
|
||||
/** 用户充值金额 */
|
||||
/** @var UserRechargeServices $userRechageService */
|
||||
$userRechageService = app()->make(UserRechargeServices::class);
|
||||
$rechargeSumField = "price";
|
||||
$whereInRecharge['paid'] = 1;
|
||||
$whereInRecharge['refund_price'] = '0.00';
|
||||
$whereInRecharge['timeKey'] = $this->TimeConvert($where['time'], $isNum);
|
||||
$whereInRecharge['store_id'] = 0;
|
||||
$totalMoney = $userRechageService->getRechargeMoneyByWhere($whereInRecharge, $rechargeSumField, $selectType, $group);
|
||||
if ($group) {
|
||||
$totalMoney = $this->trendYdata((array)$totalMoney, $whereInRecharge['timeKey']);
|
||||
}
|
||||
return $totalMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台手动充值
|
||||
* @param array $where
|
||||
* @param string $selectType
|
||||
* @param string $group
|
||||
* @param bool $isNum
|
||||
* @return array|float|int
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getBillYeTotalMoney(array $where, string $selectType, string $group = "", bool $isNum = false)
|
||||
{
|
||||
/** 后台用户充值金额 */
|
||||
$rechargeSumField = "number";
|
||||
$whereInRecharge['pm'] = 1;
|
||||
$whereInRecharge['type'] = 'system_add';
|
||||
$whereInRecharge['timeKey'] = $this->TimeConvert($where['time'], $isNum);
|
||||
$whereInRecharge['store_id'] = 0;
|
||||
/** @var UserMoneyServices $userMoneyServices */
|
||||
$userMoneyServices = app()->make(UserMoneyServices::class);
|
||||
$totalMoney = $userMoneyServices->getRechargeMoneyByWhere($whereInRecharge, $rechargeSumField, $selectType, $group);
|
||||
if ($group) {
|
||||
$totalMoney = $this->trendYdata((array)$totalMoney, $whereInRecharge['timeKey']);
|
||||
}
|
||||
return $totalMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* 购买会员总额
|
||||
* @param array $where
|
||||
* @param string $selectType
|
||||
* @param string $group
|
||||
* @param bool $isNum
|
||||
* @return array|mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getMemberTotalMoney(array $where, string $selectType, string $group = "", bool $isNum = false)
|
||||
{
|
||||
|
||||
/** 购买会员 */
|
||||
/** @var OtherOrderServices $otherOrderService */
|
||||
$otherOrderService = app()->make(OtherOrderServices::class);
|
||||
$memberSumField = "pay_price";
|
||||
$whereInMember['type'] = 1;
|
||||
$whereInMember['paid'] = 1;
|
||||
$whereInMember['store_id'] = 0;
|
||||
if (isset($where['pay_type'])) {
|
||||
$whereInMember['pay_type'] = $where['pay_type'];
|
||||
} else {
|
||||
//$whereInMember['pay_type_no'] = 'yue';
|
||||
}
|
||||
$whereInMember['timeKey'] = $this->TimeConvert($where['time'], $isNum);
|
||||
$totalMoney = $otherOrderService->getMemberMoneyByWhere($whereInMember, $memberSumField, $selectType, $group);
|
||||
if ($group) {
|
||||
$totalMoney = $this->trendYdata((array)$totalMoney, $whereInMember['timeKey']);
|
||||
}
|
||||
return $totalMoney;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 线下付款总额
|
||||
* @param array $where
|
||||
* @param string $selectType
|
||||
* @param string $group
|
||||
* @param bool $isNum
|
||||
* @return array|mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getOfflineTotalMoney(array $where, string $selectType, string $group = "", bool $isNum = false)
|
||||
{
|
||||
/** 线下付款总额 */
|
||||
/** @var OtherOrderServices $otherOrderService */
|
||||
$otherOrderService = app()->make(OtherOrderServices::class);
|
||||
$offlineSumField = "pay_price";
|
||||
$whereOffline['type'] = 3;
|
||||
$whereOffline['paid'] = 1;
|
||||
$whereOffline['store_id'] = 0;
|
||||
// $whereOffline['pay_type_no'] = 'yue';
|
||||
$whereOffline['timeKey'] = $this->TimeConvert($where['time'], $isNum);
|
||||
$totalMoney = $otherOrderService->getMemberMoneyByWhere($whereOffline, $offlineSumField, $selectType, $group);
|
||||
if ($group) {
|
||||
$totalMoney = $this->trendYdata((array)$totalMoney, $whereOffline['timeKey']);
|
||||
}
|
||||
return $totalMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理Y坐标数据
|
||||
* @param array $data
|
||||
* @param array $timeKey
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function trendYdata(array $data, array $timeKey)
|
||||
{
|
||||
$hourMoney = array();
|
||||
$timeData = array();
|
||||
//获取日期之间的天数
|
||||
$getDayRange = function ($date, $timeKey) {
|
||||
$datearr = [];
|
||||
$stime = strtotime($timeKey['start_time']);
|
||||
$etime = strtotime($timeKey['end_time']);
|
||||
while ($stime <= $etime) {
|
||||
$datearr['x'][] = date($date, $stime);
|
||||
$datearr['y'][] = date($date, $stime);
|
||||
$stime = $stime + 86400;
|
||||
}
|
||||
return $datearr;
|
||||
};
|
||||
//获取日期之间的月份
|
||||
$getMonthRange = function ($date, $timeKey) {
|
||||
$datearr = [];
|
||||
$stime = date('Y-m-d', strtotime($timeKey['start_time']));
|
||||
$etime = date('Y-m-d', strtotime($timeKey['end_time']));
|
||||
$start = new \DateTime($stime);
|
||||
$end = new \DateTime($etime);
|
||||
$interval = \DateInterval::createFromDateString('1 month');
|
||||
$period = new \DatePeriod($start, $interval, $end);
|
||||
foreach ($period as $dt) {
|
||||
$datearr['x'][] = $dt->format($date);
|
||||
$datearr['y'][] = $dt->format($date);
|
||||
}
|
||||
return $datearr;
|
||||
};
|
||||
if ($timeKey['days'] == 1) {
|
||||
for ($i = 0; $i <= 24; $i++) {
|
||||
// $timeData['x'][] = (string)($i < 10 ? ('0' . $i) : $i);
|
||||
$timeData['y'][] = $i < 10 ? ('0' . $i) : $i;
|
||||
//$timeData['y'][] = $i < 10 ? ('0' . $i . ":00") : $i . ":00";
|
||||
$timeData['x'][] = $i < 10 ? ('0' . $i . ":00") : $i . ":00";
|
||||
}
|
||||
} elseif ($timeKey['days'] == 30) {
|
||||
$timeData = $getDayRange('Y-m-d', $timeKey);
|
||||
} elseif ($timeKey['days'] >= 365) {
|
||||
$timeData = $getMonthRange('Y-m', $timeKey);
|
||||
} elseif ($timeKey['days'] > 1 && $timeKey['days'] < 30) {
|
||||
$timeData = $getDayRange('Y-m-d', $timeKey);
|
||||
} elseif ($timeKey['days'] > 30) {
|
||||
$timeData = $getMonthRange('Y-m', $timeKey);
|
||||
}
|
||||
if ($data) {
|
||||
$hourMoney = array_column($data, 'number', 'time');
|
||||
}
|
||||
$y = array();
|
||||
foreach ($timeData['y'] as $k => $v) {
|
||||
if (array_key_exists($v, $hourMoney)) {
|
||||
$y[$v] = $hourMoney[$v];
|
||||
} else {
|
||||
$y[$v] = 0;
|
||||
}
|
||||
}
|
||||
return ['x' => $timeData['x'], 'y' => $y];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取环比时间类型
|
||||
* @param $timeKey
|
||||
* @return string
|
||||
*/
|
||||
public function chainTime($timeKey)
|
||||
{
|
||||
switch ($timeKey) {
|
||||
case "today" :
|
||||
return "yestoday";
|
||||
case "month" :
|
||||
return "last_month";
|
||||
case "year" :
|
||||
return "last_year";
|
||||
default :
|
||||
return "other";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
557
app/services/statistic/UserStatisticServices.php
Normal file
557
app/services/statistic/UserStatisticServices.php
Normal file
@@ -0,0 +1,557 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\services\statistic;
|
||||
|
||||
use app\services\BaseServices;
|
||||
use app\services\other\export\ExportServices;
|
||||
use app\services\order\OtherOrderServices;
|
||||
use app\services\order\StoreOrderServices;
|
||||
use app\services\user\UserAddressServices;
|
||||
use app\services\user\UserRechargeServices;
|
||||
use app\services\user\UserServices;
|
||||
use app\services\user\UserVisitServices;
|
||||
use app\services\user\UserWechatuserServices;
|
||||
use app\services\wechat\WechatUserServices;
|
||||
use crmeb\exceptions\AdminException;
|
||||
|
||||
/**
|
||||
* Class UserStatisticServices
|
||||
* @package app\services\statistic
|
||||
*/
|
||||
class UserStatisticServices extends BaseServices
|
||||
{
|
||||
/**
|
||||
* 基本概况
|
||||
* @param $where
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBasic($where)
|
||||
{
|
||||
$time = explode('-', $where['time']);
|
||||
if (count($time) != 2) throw new AdminException('参数错误');
|
||||
/** @var UserVisitServices $userVisit */
|
||||
$userVisit = app()->make(UserVisitServices::class);
|
||||
/** @var UserServices $user */
|
||||
$user = app()->make(UserServices::class);
|
||||
/** @var StoreOrderServices $order */
|
||||
$order = app()->make(StoreOrderServices::class);
|
||||
/** @var UserRechargeServices $recharge */
|
||||
$recharge = app()->make(UserRechargeServices::class);
|
||||
/** @var OtherOrderServices $otherOrder */
|
||||
$otherOrder = app()->make(OtherOrderServices::class);
|
||||
|
||||
$toEndtime = [0, $time[1]];
|
||||
$cumulativeUserWhere = [['add_time', 'between', $toEndtime], ['user_type', '=', $where['channel_type']]];
|
||||
$cumulativeRechargePeopleWhere = ['paid' => 1, 'time' => $toEndtime, 'timeKey' => 'pay_time', 'channel_type' => $where['channel_type']];
|
||||
$cumulativePayPeopleWhere = ['time' => $toEndtime, 'timeKey' => 'pay_time', 'paid' => 1, 'channel_type' => $where['channel_type']];
|
||||
|
||||
$now['people'] = $userVisit->getDistinctCount($where, 'uid');//访客数
|
||||
$now['browse'] = $userVisit->count($where);//访问量
|
||||
$now['newUser'] = $user->getWithTrashedCount($where['channel_type'] ? ['user_type' => $where['channel_type']] : [], $time);//新增用户数
|
||||
$now['payPeople'] = $order->getDistinctCount($where + ['paid' => 1, 'timeKey' => 'pay_time'], 'uid');//成交用户数
|
||||
$now['payPercent'] = bcmul((string)($now['people'] > 0 ? bcdiv($now['payPeople'], $now['people'], 4) : 0), '100', 2);//访问-付款转化率
|
||||
$now['payUser'] = $otherOrder->getDistinctCount($where + ['paid' => 1, "member_type" => -1], 'uid');//激活付费会员数
|
||||
$now['rechargePeople'] = $recharge->getDistinctCount($where + ['paid' => 1, 'timeKey' => 'pay_time'], 'uid');//充值用户数
|
||||
$totalPayPrice = $order->sum($where + ['paid' => 1], 'pay_price', true);
|
||||
$now['payPrice'] = floatval($now['payPeople'] > 0 ? bcdiv($totalPayPrice, $now['payPeople'], 2) : 0);//客单价
|
||||
$now['cumulativeUser'] = $user->getWithTrashedCount($where['channel_type'] ? ['user_type' => $where['channel_type']] : [], $toEndtime);//累计用户数
|
||||
$now['cumulativePayUser'] = count($otherOrder->getPayUserCount(strtotime($time[1]), $where['channel_type']));//到截至日期有付费会员状态的会员数
|
||||
$now['cumulativeRechargePeople'] = $recharge->getDistinctCount($cumulativeRechargePeopleWhere, 'uid');//累计充值用户数
|
||||
$now['cumulativePayPeople'] = $order->getDistinctCount($cumulativePayPeopleWhere, 'uid');//累计成交用户数
|
||||
|
||||
|
||||
$dayNum = (strtotime($time[1]) - strtotime($time[0])) / 86400 + 1;
|
||||
$lastTime = [
|
||||
date("Y/m/d", strtotime("-$dayNum days", strtotime($time[0]))),
|
||||
date("Y/m/d", strtotime("-1 days", strtotime($time[0])))
|
||||
];
|
||||
$where['time'] = implode('-', $lastTime);
|
||||
$toEndtime = implode('-', [0, $lastTime[1]]);
|
||||
$last['people'] = $userVisit->getDistinctCount($where, 'uid');//访客数
|
||||
$last['browse'] = $userVisit->count($where);//访问量
|
||||
$last['newUser'] = $user->count($where + ['user_type' => $where['channel_type']]);//新增用户数
|
||||
$last['payPeople'] = $order->getDistinctCount($where + ['paid' => 1, 'timeKey' => 'pay_time'], 'uid');//成交用户数
|
||||
$last['payPercent'] = bcmul((string)($last['people'] > 0 ? bcdiv($last['payPeople'], $last['people'], 4) : 0), '100', 2);//访问-付款转化率
|
||||
$last['payUser'] = $otherOrder->getDistinctCount($where + ['paid' => 1], 'uid');//激活付费会员数
|
||||
$last['rechargePeople'] = $recharge->getDistinctCount($where + ['paid' => 1, 'timeKey' => 'pay_time'], 'uid');//充值用户数
|
||||
$totalPayPrice = $order->sum($where + ['paid' => 1], 'pay_price', true);
|
||||
$last['payPrice'] = floatval($last['payPeople'] > 0 ? bcdiv($totalPayPrice, $last['payPeople'], 2) : 0);//客单价
|
||||
$cumulativeUserWhere['time'] = $toEndtime;
|
||||
$last['cumulativeUser'] = $user->count($cumulativeUserWhere);//累计用户数
|
||||
$last['cumulativePayUser'] = count($otherOrder->getPayUserCount(strtotime($lastTime[1]) + 86400, $where['channel_type']));//到截至日期有付费会员状态的会员数
|
||||
$cumulativeRechargePeopleWhere['time'] = $toEndtime;
|
||||
$last['cumulativeRechargePeople'] = $recharge->getDistinctCount($cumulativeRechargePeopleWhere, 'uid');//累计充值用户数
|
||||
$cumulativePayPeopleWhere['time'] = $toEndtime;
|
||||
$last['cumulativePayPeople'] = $order->getDistinctCount($cumulativePayPeopleWhere, 'uid');//累计成交用户数
|
||||
|
||||
//组合数据,计算环比
|
||||
$data = [];
|
||||
foreach ($now as $key => $item) {
|
||||
$data[$key]['num'] = $item;
|
||||
$data[$key]['last_num'] = $last[$key];
|
||||
$num = $last[$key] > 0 ? $last[$key] : 1;
|
||||
$data[$key]['percent'] = bcmul((string)bcdiv((string)($item - $last[$key]), (string)$num, 4), 100, 2);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户趋势
|
||||
* @param $where
|
||||
* @param $excel
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTrend($where, $excel = false)
|
||||
{
|
||||
$time = explode('-', $where['time']);
|
||||
$channelType = $where['channel_type'];
|
||||
if (count($time) != 2) throw new AdminException('参数错误');
|
||||
$dayCount = (strtotime($time[1]) - strtotime($time[0])) / 86400 + 1;
|
||||
$data = [];
|
||||
if ($dayCount == 1) {
|
||||
$data = $this->trend($time, $channelType, 0, $excel);
|
||||
} elseif ($dayCount > 1 && $dayCount <= 31) {
|
||||
$data = $this->trend($time, $channelType, 1, $excel);
|
||||
} elseif ($dayCount > 31 && $dayCount <= 92) {
|
||||
$data = $this->trend($time, $channelType, 3, $excel);
|
||||
} elseif ($dayCount > 92) {
|
||||
$data = $this->trend($time, $channelType, 30, $excel);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户趋势
|
||||
* @param $time
|
||||
* @param $channelType
|
||||
* @param $num
|
||||
* @param $excel
|
||||
* @return array
|
||||
*/
|
||||
public function trend($time, $channelType, $num, $excel)
|
||||
{
|
||||
/** @var UserServices $user */
|
||||
$user = app()->make(UserServices::class);
|
||||
/** @var UserVisitServices $userVisit */
|
||||
$userVisit = app()->make(UserVisitServices::class);
|
||||
/** @var StoreOrderServices $order */
|
||||
$order = app()->make(StoreOrderServices::class);
|
||||
/** @var UserRechargeServices $recharge */
|
||||
$recharge = app()->make(UserRechargeServices::class);
|
||||
/** @var OtherOrderServices $otherOrder */
|
||||
$otherOrder = app()->make(OtherOrderServices::class);
|
||||
|
||||
$newPeople = $visitPeople = $paidPeople = $rechargePeople = $vipPeople = [];
|
||||
$newPeople['name'] = '新增用户数';
|
||||
$visitPeople['name'] = '访客数';
|
||||
$paidPeople['name'] = '成交用户数';
|
||||
$rechargePeople['name'] = '充值用户';
|
||||
$vipPeople['name'] = '激活付费用户数';
|
||||
if ($num == 0) {
|
||||
$xAxis = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'];
|
||||
$timeType = '%H';
|
||||
} elseif ($num != 0) {
|
||||
$dt_start = strtotime($time[0]);
|
||||
$dt_end = strtotime($time[1]);
|
||||
while ($dt_start <= $dt_end) {
|
||||
if ($num == 30) {
|
||||
$xAxis[] = date('Y-m', $dt_start);
|
||||
$dt_start = strtotime("+1 month", $dt_start);
|
||||
$timeType = '%Y-%m';
|
||||
} else {
|
||||
$xAxis[] = date('m-d', $dt_start);
|
||||
$dt_start = strtotime("+$num day", $dt_start);
|
||||
$timeType = '%m-%d';
|
||||
}
|
||||
}
|
||||
}
|
||||
$visitPeople = array_column($userVisit->getTrendData($time, $channelType, $timeType, 'count(distinct(uid))'), 'num', 'days');
|
||||
$newPeople = array_column($user->getTrendData($time, $channelType, $timeType), 'num', 'days');
|
||||
$paidPeople = array_column($order->getTrendData($time, $channelType, $timeType, 'count(distinct(uid))'), 'num', 'days');
|
||||
$rechargePeople = array_column($recharge->getTrendData($time, $channelType, $timeType, 'count(distinct(uid))'), 'num', 'days');
|
||||
$vipPeople = array_column($otherOrder->getTrendData($time, $channelType, $timeType, 'count(distinct(uid))'), 'num', 'days');
|
||||
if ($excel) {
|
||||
$browsePeople = array_column($userVisit->getTrendData($time, $channelType, $timeType, 'count(id)'), 'num', 'days');
|
||||
$paidPrice = array_column($order->getTrendData($time, $channelType, $timeType, 'sum(pay_price)'), 'num', 'days');
|
||||
foreach ($xAxis as &$item) {
|
||||
if (isset($paidPeople[$item]) && isset($visitPeople[$item])) {
|
||||
$changes = bcmul(bcdiv((string)$paidPeople[$item], (string)$visitPeople[$item], 4), 100, 2);
|
||||
$changes = $changes > 100 ? 100 : $changes;
|
||||
} else {
|
||||
$changes = 0;
|
||||
}
|
||||
$data[] = [
|
||||
'time' => $item,
|
||||
'user' => $visitPeople[$item] ?? 0,
|
||||
'browse' => $browsePeople[$item] ?? 0,
|
||||
'new' => $newPeople[$item] ?? 0,
|
||||
'paid' => $paidPeople[$item] ?? 0,
|
||||
'changes' => $changes,
|
||||
'vip' => $vipPeople[$item] ?? 0,
|
||||
'recharge' => $rechargePeople[$item] ?? 0,
|
||||
'payPrice' => isset($paidPrice[$item]) && isset($paidPeople[$item]) ? bcdiv((string)$paidPrice[$item], (string)$paidPeople[$item], 2) : 0,
|
||||
// 'cumulativeUser' => $user->getCount($userWhere),
|
||||
// 'cumulativeVip' => $otherOrder->getPayUserCount($endTime, $channelType),
|
||||
// 'cumulativeRecharge' => $recharge->getCount($rechargeWhere),
|
||||
// 'cumulativePaid' => $order->getCount($payWhere),
|
||||
];
|
||||
}
|
||||
/** @var ExportServices $exportService */
|
||||
$exportService = app()->make(ExportServices::class);
|
||||
return $exportService->userTrade($data);
|
||||
} else {
|
||||
$data = $series = [];
|
||||
foreach ($xAxis as $item) {
|
||||
$data['新增用户数'][] = isset($newPeople[$item]) ? intval($newPeople[$item]) : 0;
|
||||
$data['访客数'][] = isset($visitPeople[$item]) ? intval($visitPeople[$item]) : 0;
|
||||
$data['成交用户数'][] = isset($paidPeople[$item]) ? intval($paidPeople[$item]) : 0;
|
||||
$data['充值用户'][] = isset($rechargePeople[$item]) ? intval($rechargePeople[$item]) : 0;
|
||||
$data['激活付费用户数'][] = isset($vipPeople[$item]) ? intval($vipPeople[$item]) : 0;
|
||||
}
|
||||
foreach ($data as $key => $item) {
|
||||
$series[] = ['name' => $key, 'value' => $item];
|
||||
}
|
||||
return compact('xAxis', 'series');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信用户信息
|
||||
* @param $where
|
||||
* @return array
|
||||
*/
|
||||
public function getWechat($where)
|
||||
{
|
||||
$time = explode('-', $where['time']);
|
||||
if (count($time) != 2) throw new AdminException('参数错误');
|
||||
/** @var WechatUserServices $user */
|
||||
$user = app()->make(WechatUserServices::class);
|
||||
|
||||
$now['subscribe'] = $user->getCount([
|
||||
['subscribe', '=', 1],
|
||||
['user_type', '=', 'wechat'],
|
||||
['subscribe_time', '>=', strtotime($time[0])],
|
||||
['subscribe_time', '<', strtotime($time[1]) + 86400]
|
||||
]);
|
||||
$now['unSubscribe'] = $user->getCount([
|
||||
['subscribe', '=', 0],
|
||||
['user_type', '=', 'wechat'],
|
||||
['subscribe_time', '<>', ''],
|
||||
['subscribe_time', '>=', strtotime($time[0])],
|
||||
['subscribe_time', '<', strtotime($time[1]) + 86400]
|
||||
]);
|
||||
$now['increaseSubscribe'] = $now['subscribe'] - $now['unSubscribe'];
|
||||
$now['cumulativeSubscribe'] = $user->getCount([['subscribe', '=', 1], ['user_type', '=', 'wechat']]);
|
||||
$now['cumulativeUnSubscribe'] = $user->getCount([
|
||||
['subscribe', '=', 0],
|
||||
['user_type', '=', 'wechat'],
|
||||
['subscribe_time', '<>', '']
|
||||
]);
|
||||
|
||||
$dayNum = (strtotime($time[1]) - strtotime($time[0])) / 86400 + 1;
|
||||
$lastTime = array(
|
||||
date("Y/m/d", strtotime("-$dayNum days", strtotime($time[0]))),
|
||||
date("Y/m/d", strtotime("-1 days", strtotime($time[0])))
|
||||
);
|
||||
$last['subscribe'] = $user->getCount([
|
||||
['subscribe', '=', 1],
|
||||
['user_type', '=', 'wechat'],
|
||||
['subscribe_time', '>=', strtotime($lastTime[0])],
|
||||
['subscribe_time', '<', strtotime($lastTime[1]) + 86400]
|
||||
]);
|
||||
$last['unSubscribe'] = $user->getCount([
|
||||
['subscribe', '=', 0],
|
||||
['user_type', '=', 'wechat'],
|
||||
['subscribe_time', '<>', ''],
|
||||
['subscribe_time', '>=', strtotime($lastTime[0])],
|
||||
['subscribe_time', '<', strtotime($lastTime[1]) + 86400]
|
||||
]);
|
||||
$last['increaseSubscribe'] = $last['subscribe'] - $last['unSubscribe'];
|
||||
$last['cumulativeSubscribe'] = $user->getCount([['subscribe', '=', 1], ['user_type', '=', 'wechat']]);
|
||||
$last['cumulativeUnSubscribe'] = $user->getCount([
|
||||
['subscribe', '=', 0],
|
||||
['user_type', '=', 'wechat'],
|
||||
['subscribe_time', '<>', '']
|
||||
]);
|
||||
|
||||
//组合数据,计算环比
|
||||
$data = [];
|
||||
foreach ($now as $key => $item) {
|
||||
$data[$key]['num'] = $item;
|
||||
$num = $last[$key] ?: 1;
|
||||
$data[$key]['percent'] = bcmul(bcdiv(($item - $last[$key]), $num, 4), 100, 2);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信用户趋势
|
||||
* @param $where
|
||||
* @return array
|
||||
*/
|
||||
public function getWechatTrend($where)
|
||||
{
|
||||
$time = explode('-', $where['time']);
|
||||
$channelType = $where['channel_type'];
|
||||
if (count($time) != 2) throw new AdminException('参数错误');
|
||||
$dayCount = (strtotime($time[1]) - strtotime($time[0])) / 86400 + 1;
|
||||
$data = [];
|
||||
if ($dayCount == 1) {
|
||||
$data = $this->wechatTrend($time, 0);
|
||||
} elseif ($dayCount > 1 && $dayCount <= 31) {
|
||||
$data = $this->wechatTrend($time, 1);
|
||||
} elseif ($dayCount > 31 && $dayCount <= 92) {
|
||||
$data = $this->wechatTrend($time, 3);
|
||||
} elseif ($dayCount > 92) {
|
||||
$data = $this->wechatTrend($time, 30);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信用户趋势
|
||||
* @param $time
|
||||
* @param $num
|
||||
* @return array
|
||||
*/
|
||||
public function wechatTrend($time, $num)
|
||||
{
|
||||
/** @var WechatUserServices $user */
|
||||
$user = app()->make(WechatUserServices::class);
|
||||
|
||||
$subscribe = $unSubscribe = $increaseSubscribe = $cumulativeSubscribe = $cumulativeUnSubscribe = [];
|
||||
if ($num == 0) {
|
||||
$xAxis = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'];
|
||||
$subscribe = array_column($user->getWechatTrendData($time, [
|
||||
['subscribe', '=', 1],
|
||||
['subscribe_time', '>=', strtotime($time[0])],
|
||||
['subscribe_time', '<', strtotime($time[1]) + 86400]
|
||||
], '%H', 'subscribe'), 'subscribe', 'days');
|
||||
$unSubscribe = array_column($user->getWechatTrendData($time, [
|
||||
['subscribe', '=', 0],
|
||||
['subscribe_time', '<>', ''],
|
||||
['subscribe_time', '>=', strtotime($time[0])],
|
||||
['subscribe_time', '<', strtotime($time[1]) + 86400]
|
||||
], '%H', 'unSubscribe'), 'unSubscribe', 'days');
|
||||
$cumulativeSubscribe = array_column($user->getWechatTrendData($time, [
|
||||
['subscribe', '=', 1]
|
||||
], '%H', 'cumulativeSubscribe'), 'cumulativeSubscribe', 'days');
|
||||
$cumulativeUnSubscribe = array_column($user->getWechatTrendData($time, [
|
||||
['subscribe', '=', 0], ['subscribe_time', '<>', '']
|
||||
], '%H', 'cumulativeUnSubscribe'), 'cumulativeUnSubscribe', 'days');
|
||||
} elseif ($num != 0) {
|
||||
$dt_start = strtotime($time[0]);
|
||||
$dt_end = strtotime($time[1]);
|
||||
while ($dt_start <= $dt_end) {
|
||||
if ($num == 30) {
|
||||
$xAxis[] = date('Y-m', $dt_start);
|
||||
$dt_start = strtotime("+1 month", $dt_start);
|
||||
$timeType = '%Y-%m';
|
||||
} else {
|
||||
$xAxis[] = date('m-d', $dt_start);
|
||||
$dt_start = strtotime("+$num day", $dt_start);
|
||||
$timeType = '%m-%d';
|
||||
}
|
||||
}
|
||||
$subscribe = array_column($user->getWechatTrendData($time, [
|
||||
['subscribe', '=', 1],
|
||||
['subscribe_time', '>=', strtotime($time[0])],
|
||||
['subscribe_time', '<', strtotime($time[1]) + 86400]
|
||||
], $timeType, 'subscribe'), 'subscribe', 'days');
|
||||
$unSubscribe = array_column($user->getWechatTrendData($time, [
|
||||
['subscribe', '=', 0],
|
||||
['subscribe_time', '<>', ''],
|
||||
['subscribe_time', '>=', strtotime($time[0])],
|
||||
['subscribe_time', '<', strtotime($time[1]) + 86400]
|
||||
], $timeType, 'unSubscribe'), 'unSubscribe', 'days');
|
||||
$cumulativeSubscribe = array_column($user->getWechatTrendData($time, [
|
||||
['subscribe', '=', 1]
|
||||
], $timeType, 'cumulativeSubscribe'), 'cumulativeSubscribe', 'days');
|
||||
$cumulativeUnSubscribe = array_column($user->getWechatTrendData($time, [
|
||||
['subscribe', '=', 0], ['subscribe_time', '<>', '']
|
||||
], $timeType, 'cumulativeUnSubscribe'), 'cumulativeUnSubscribe', 'days');
|
||||
}
|
||||
$data = $series = [];
|
||||
foreach ($xAxis as $item) {
|
||||
$data['新增关注用户'][] = isset($subscribe[$item]) ? $subscribe[$item] : 0;
|
||||
$data['新增取关用户'][] = isset($unSubscribe[$item]) ? $unSubscribe[$item] : 0;
|
||||
$data['累计关注用户'][] = isset($cumulativeSubscribe[$item]) ? $cumulativeSubscribe[$item] : 0;
|
||||
$data['累计取关用户'][] = isset($cumulativeUnSubscribe[$item]) ? $cumulativeUnSubscribe[$item] : 0;
|
||||
}
|
||||
foreach ($data['新增关注用户'] as $keys => $items) {
|
||||
$data['净增用户数'][] = $data['新增关注用户'][$keys] - $data['新增取关用户'][$keys];
|
||||
}
|
||||
foreach ($data as $key => $item) {
|
||||
$series[] = ['name' => $key, 'value' => $item];
|
||||
}
|
||||
return compact('xAxis', 'series');
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户地域图表
|
||||
* @param $where
|
||||
* @return array
|
||||
*/
|
||||
public function getRegionV1($where)
|
||||
{
|
||||
$time = explode('-', $where['time']);
|
||||
$channelType = $where['channel_type'];
|
||||
if (count($time) != 2) throw new AdminException('参数错误');
|
||||
|
||||
/** @var UserVisitServices $userVisit */
|
||||
$userVisit = app()->make(UserVisitServices::class);
|
||||
/** @var StoreOrderServices $order */
|
||||
$order = app()->make(StoreOrderServices::class);
|
||||
/** @var UserAddressServices $useAddress */
|
||||
$useAddress = app()->make(UserAddressServices::class);
|
||||
|
||||
$all = $useAddress->getRegionAll($time, $channelType);
|
||||
$new = $useAddress->getRegionNew($time, $channelType);
|
||||
$visit = $userVisit->getRegion($time, $channelType);
|
||||
$payPrice = $order->getRegion($time, $channelType);
|
||||
if ($new) $new = array_combine(array_column($new, 'province'), $new);
|
||||
if ($visit) $visit = array_combine(array_column($visit, 'province'), $visit);
|
||||
$newPayPrice = [];
|
||||
if ($payPrice) {
|
||||
foreach ($payPrice as $item) {
|
||||
if (isset($newPayPrice[$item['province']])) {
|
||||
$newPayPrice[$item['province']]['payPrice'] = bcadd((string)$newPayPrice[$item['province']]['payPrice'], (string)$item['payPrice'], 2);
|
||||
} else {
|
||||
$newPayPrice[$item['province']] = ['province' => $item['province'], 'payPrice' => $item['payPrice']];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($visit[""])) {
|
||||
$all[] = ["province" => ''];
|
||||
}
|
||||
$handleAddress = function ($p, $visitArr) {
|
||||
return $visitArr[$p . '市'] ?? $visitArr[$p . '省'] ?? $visitArr[$p . '自治区'] ?? [];
|
||||
};
|
||||
foreach ($all as &$item) {
|
||||
if ($item['province'] == '') $item['province'] = '未知';
|
||||
if (!isset($item['allNum'])) $item['allNum'] = 0;
|
||||
$item['newNum'] = intval($new[$item['province']]['newNum'] ?? 0);
|
||||
$item['visitNum'] = intval($handleAddress($item['province'], $visit)['visitNum'] ?? 0);
|
||||
$item['payPrice'] = floatval($newPayPrice[$item['province']]['payPrice'] ?? 0);
|
||||
}
|
||||
$data = array_values($all);
|
||||
$last_names = array_column($data, $where['sort']);
|
||||
array_multisort($last_names, SORT_DESC, $data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户地域图表
|
||||
* @param $where
|
||||
* @return array
|
||||
*/
|
||||
public function getRegion($where)
|
||||
{
|
||||
$time = explode('-', $where['time']);
|
||||
$channelType = $where['channel_type'];
|
||||
if (count($time) != 2) throw new AdminException('参数错误');
|
||||
|
||||
/** @var UserVisitServices $userVisit */
|
||||
$userVisit = app()->make(UserVisitServices::class);
|
||||
/** @var UserServices $userService */
|
||||
$userService = app()->make(UserServices::class);
|
||||
/** @var StoreOrderServices $order */
|
||||
$order = app()->make(StoreOrderServices::class);
|
||||
|
||||
/** @var UserWechatuserServices $wechatUser */
|
||||
$wechatUser = app()->make(UserWechatuserServices::class);
|
||||
|
||||
$all = $wechatUser->getRegionAll($time, $channelType);
|
||||
$new = $wechatUser->getRegionNew($time, $channelType);
|
||||
$visit = $userVisit->getRegion($time, $channelType);
|
||||
$payPrice = $order->getRegion($time, $channelType);
|
||||
foreach ($all as $key1 => $item1) {
|
||||
foreach ($new as $key2 => $item2) {
|
||||
if ($item1['province'] == $item2['province']) {
|
||||
$all[$key1]['newNum'] = $item2['newNum'];
|
||||
unset($new[$key2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$all = array_merge($all, $new);
|
||||
foreach ($all as $key1 => $item1) {
|
||||
foreach ($visit as $key3 => $item3) {
|
||||
if ($item1['province'] == $item3['province']) {
|
||||
$all[$key1]['visitNum'] = $item3['visitNum'];
|
||||
unset($visit[$key3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$all = array_merge($all, $visit);
|
||||
foreach ($all as $key1 => $item1) {
|
||||
foreach ($payPrice as $key3 => $item3) {
|
||||
if ($item1['province'] == $item3['province']) {
|
||||
$all[$key1]['payPrice'] = $item3['payPrice'];
|
||||
unset($payPrice[$key3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$all = array_merge($all, $payPrice);
|
||||
foreach ($all as &$item) {
|
||||
if ($item['province'] == '') $item['province'] = '未知';
|
||||
if (!isset($item['allNum'])) $item['allNum'] = 0;
|
||||
if (!isset($item['newNum'])) $item['newNum'] = 0;
|
||||
if (!isset($item['visitNum'])) $item['visitNum'] = 0;
|
||||
if (!isset($item['payPrice'])) {
|
||||
$item['payPrice'] = 0;
|
||||
} else {
|
||||
$item['payPrice'] = floatval($item['payPrice']);
|
||||
}
|
||||
}
|
||||
$data = array_values($all);
|
||||
$last_names = array_column($data, $where['sort']);
|
||||
array_multisort($last_names, SORT_DESC, $data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户性别
|
||||
* @param $where
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSex($where)
|
||||
{
|
||||
$time = explode('-', $where['time']);
|
||||
$channelType = $where['channel_type'];
|
||||
if (count($time) != 2) throw new AdminException('参数错误');
|
||||
|
||||
/** @var UserWechatuserServices $wechatUser */
|
||||
$wechatUser = app()->make(UserWechatuserServices::class);
|
||||
|
||||
$data = $wechatUser->getSex($time, $channelType);
|
||||
|
||||
$oneData = [
|
||||
['value' => 0, 'name' => '未知', 'name_key' => 0],
|
||||
['value' => 0, 'name' => '男', 'name_key' => 1],
|
||||
['value' => 0, 'name' => '女', 'name_key' => 2],
|
||||
];
|
||||
foreach ($data as $item) {
|
||||
if ($item['sex'] == 0) {
|
||||
$oneData[0]['value'] = $item['number'];
|
||||
break;
|
||||
} elseif ($item['sex'] == 1) {
|
||||
$oneData[1]['value'] = $item['number'];
|
||||
break;
|
||||
} else {
|
||||
$oneData[2]['value'] = $item['number'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $oneData;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user