ownerService = app(OwnerService::class); } /** * @param $start * @param $end * @param null $ownerIds ; * @param string $unit * @param $user * @return mixed */ public function get($start, $end, $ownerIds = null, $unit = '日', $user) { $resultByCache = $this->getByCache($start, $end, $ownerIds, $unit, $user); if (!($resultByCache['unExistingOrders'])) return $resultByCache['resultOrders']; $resultByOrderCountingRecords = $this->getByDatabase($resultByCache['unExistingOrders'], $unit); $this->createByDatabase($resultByOrderCountingRecords['unExistingOrders'], $unit); $this->getByDatabase($resultByCache['unExistingOrders'], $unit); $resultByCache = $this->getByCache($start, $end, $ownerIds, $unit, $user); return $resultByCache['resultOrders']; } public function orderCountingRecords($start, $end, $ownerIds = null, $unit = '日', $user = null) { $key = 'orderCountingRecords_' . $start . '_' . $end . '_' . $unit . '_' . Auth::user()->id; return Cache::remember($key, 60, function () use ($start, $end, $unit, $ownerIds, $user) { $orders = $this->get($start, $end, null, $unit, null); $dataList = collect(); $orders->groupBy('date_target')->each(function ($items) use (&$dataList, $unit) { $counter = $items->reduce(function ($sum, $item) { return $sum + $item->amount; }, 0); $date_target = $items[0]->date_target; if ($unit == '周') { $date_target = (new DateTime())->setISODate(Str::of($date_target)->explode('-')[0], Str::of($date_target)->explode('-')[1])->format('yy-m-d'); } $dataList->push([ 'counter' => $counter, 'date_target' => $date_target, ]); }); return $dataList->sortBy("date_target"); }); } /** * @param $start * @param $end * @param null $ownerIds * @param null $user * @return \Illuminate\Support\Collection|\Tightenco\Collect\Support\Collection */ public function logisticsCountingRecords($start, $end, $ownerIds = null, $user = null) { $key = 'logisticsCountingRecords_' . $start . '_' . $end . '_' . Auth::user()->id; return Cache::remember($key, 600, function () use ($start, $end, $ownerIds, $user) { $dataList = collect(); $resultOrders = $this->get($start, $end, $ownerIds, '日', $user); $resultOrders->groupBy('logistic_id')->each(function ($item) use (&$dataList) { $counter = $item->reduce(function ($sum, $item) { return $sum + $item->amount; }, 0); $dataList->push([ 'value' => $counter, 'logistic_id' => $item[0]->logistic_id, ]); }); $map = []; $logistics = Logistic::query()->whereIn('id', data_get($dataList, '*.logistic_id'))->get(); $logistics->each(function ($logistic) use (&$map) { $map[$logistic->id] = $logistic; }); return $dataList->map(function (&$item) use ($map) { $logistic = $map[$item['logistic_id']] ?? ''; $item['name'] = $logistic->name ?? ''; return $item; }); }); } public function warehouseCountingRecords($start, $end, $ownerIds = null, $user = null) { $key = 'warehouseCountingRecords_' . $start . '_' . $end . '_' . Auth::user()->id; return Cache::remember($key, 600, function () use ($start, $end, $ownerIds, $user) { $dataList = collect(); $resultOrders = $this->get($start, $end, $ownerIds, '日', $user); $resultOrders->groupBy('warehouse_id')->each(function ($item) use (&$dataList) { $counter = $item->reduce(function ($sum, $item) { return $sum + $item->amount; }, 0); $dataList->push([ 'value' => $counter, 'warehouse_id' => $item[0]->warehouse_id, ]); }); $map = []; $logistics = Warehouse::query()->whereIn('id', data_get($dataList, '*.warehouse_id'))->get(); $logistics->each(function ($warehouse) use (&$map) { $map[$warehouse->id] = $warehouse; }); return $dataList->map(function (&$item) use ($map) { $warehouse = $map[$item['warehouse_id']] ?? ''; $item['code'] = $warehouse->name ?? ''; switch ($item['code']) { case 'WH01': $item['name'] = '松江一仓'; break; case 'WH02': $item['name'] = '松江二仓'; break; case 'WH03': $item['name'] = '嘉定一仓'; break; default: $item['name'] = '仓库为空'; break; } return $item; }); }); } /** * @param $start * @param $end * @param null $ownerIds * @param string $unit * @param $user * @return array */ public function getByCache($start, $end, $ownerIds = null, $unit = '日', $user) {// Order[] results, Array [$date=>[$ownerIds]] $countingOwnerIds = $this->getCountingOwnerIds($ownerIds, $user); $resultOrders = collect(); $unExistingOrders = []; $dateArray = $this->periodDateToArray($start, $end, $unit); foreach ($dateArray as $dateStr) { foreach ($countingOwnerIds as $ownerId) { $key = "order_counting_records_{$dateStr}_{$ownerId}_{$unit}"; $orders = Cache::get($key); if ($orders) { $orders->each(function ($item) use (&$resultOrders) { $resultOrders->push($item); }); continue; } $unExistingOrders[$dateStr][] = $ownerId; } } return ['resultOrders' => $resultOrders, 'unExistingOrders' => $unExistingOrders]; } public function getByDatabase($targetOwnerIdsUnderDates, $unit = '日') {// Order[] results, Array [$date=>[$ownerIds]] $orderSqlBuilder = OrderCountingRecord::query(); foreach ($targetOwnerIdsUnderDates as $date => $owners) { $orderSqlBuilder->orWhere(function ($query) use ($owners, $date, $unit) { $query->whereIn('owner_id', $owners)->where('date_target', $date)->where('counting_unit', $unit); }); } $resultOrders = $orderSqlBuilder->get(); $resultOrders->groupBy(['date_target', 'owner_id'])->each(function ($item, $dateStr) use ($unit) { $item->each(function ($item, $owner_id) use ($dateStr, $unit) { $key = "order_counting_records_{$dateStr}_{$owner_id}_{$unit}"; $ttl = 3600 * 24; if ($dateStr == Carbon::now()->toDateString()) { $ttl = 70; } Cache::put($key, $item, $ttl); }); }); $map = []; $resultOrders->each(function ($item) use (&$map) { $key = 'owner_id=' . $item->owner_id . ' date_target' . $item->date_target; $map[$key] = true; }); foreach ($targetOwnerIdsUnderDates as $dateStr => $ownerIds) { foreach ($ownerIds as $key => $ownerId) { $key1 = 'owner_id=' . $ownerId . ' date_target' . $dateStr; if (isset($map[$key1]) && $this->isNotCurrentDate($dateStr)) { //中间表查找到数据,并且时间不是当前日期 unset($targetOwnerIdsUnderDates[$dateStr][$key]); } } } return ['resultOrders' => $resultOrders, 'unExistingOrders' => $targetOwnerIdsUnderDates]; } public function createByDatabase($targetOwnerIdsUnderDates, $unit = '日') {// Order[] results] switch ($unit) { case '日': $resultOrders = $this->getCreateByDatabaseUnitDay($targetOwnerIdsUnderDates); break; case'周': $resultOrders = $this->getCreateByDatabaseUnitWeek($targetOwnerIdsUnderDates); break; case'月': $resultOrders = $this->getCreateByDatabaseUnitMonth($targetOwnerIdsUnderDates); break; default: $resultOrders = collect(); break; } $result = collect(); $isHasCurrentDate = false; $currentDate = null; foreach ($targetOwnerIdsUnderDates as $dateStr => $ownerIds) { if ($this->isNotCurrentDate($dateStr)) { foreach ($ownerIds as $ownerId) { if ($resultOrders->where('date_target', $dateStr)->where('owner_id', $ownerId)->count() == 0) { $result->push([ 'owner_id' => $ownerId, 'shop_id' => null, 'warehouse_id' => null, 'logistic_id' => null, 'date_target' => $dateStr, 'counting_unit' => $unit, 'amount' => 0, ]); } } } else { //查询范围包含当天 $isHasCurrentDate = true; $currentDate = $dateStr; } } $resultOrders->each(function ($order) use (&$result, $unit) { $orderCountingRecord = new OrderCountingRecord([ 'owner_id' => $order->owner_id, 'shop_id' => $order->shop_id, 'warehouse_id' => $order->warehouse_id, 'logistic_id' => $order->logistic_id, 'date_target' => $order->date_target, 'counting_unit' => $unit, 'amount' => $order->amounts, ]); $result->push($orderCountingRecord); }); if ($isHasCurrentDate) { //删除OrderCountingRecord表中与当前日期相关的数据,之后的批量插入重新插入这部分数据 OrderCountingRecord::query()->where('date_target', $currentDate)->where('counting_unit', $unit)->delete(); } OrderCountingRecord::query()->insert($result->toArray()); return ['resultOrders' => $result]; } public function periodDateToArray($start, $end, $unit = '日') { $dataArray = []; switch ($unit) { case '日'; foreach (Carbon::parse($start)->daysUntil($end, 1)->toArray() as $item) { $dataArray[] = $item->toDateString(); } break; case '周'; foreach (Carbon::parse($start)->weeksUntil($end, 1)->toArray() as $item) { $dataArray[] = $item->year . '-' . $item->week . ''; } break; case '月'; foreach (Carbon::parse($start)->monthsUntil($end, 1)->toArray() as $item) { $dataArray[] = $item->year . '-' . $item->format('m') . ''; } break; case '年'; foreach (Carbon::parse($start)->yearsUntil($end, 1)->toArray() as $item) { $dataArray[] = $item->year . '-' . $item->month . ''; } break; default: break; } return $dataArray; } /** * @param $ownerIds * @return array */ public function getCountingOwnerIds($ownerIds = null, $user): array { if ($user == null) { $user = auth()->user(); } /** @var UserService $userService */ $userService = app('UserService'); $permittingOwnerIds = $userService->getPermittingOwnerIds($user); if (!$ownerIds) { return $permittingOwnerIds; } return Cache::remember( 'PermittingOwnerIds' . '_' . auth()->user()->id . '_' . implode('_', $ownerIds), 600, function () use ($ownerIds, $permittingOwnerIds) { /** @var User $user */ return array_intersect($ownerIds, $permittingOwnerIds); }); } /** * @param $targetOwnerIdsUnderDates * @return Builder[]|Collection */ private function getCreateByDatabaseUnitDay($targetOwnerIdsUnderDates) { $orderSqlBuilder = Order::query()->selectRaw("owner_id,warehouse_id,shop_id,logistic_id,count(1) as amounts ,DATE_FORMAT(created_at,'%Y-%m-%d') as date_target"); foreach ($targetOwnerIdsUnderDates as $dateStr => $ownerIds) { $orderSqlBuilder->orWhere(function ($query) use ($ownerIds, $dateStr) { $query->whereIn('owner_id', $ownerIds)->where('created_at', '>', $dateStr)->where('created_at', '<', Carbon::parse($dateStr)->addDay()->toDateString())->where('wms_status', '订单完成'); }); } return $orderSqlBuilder->groupBy(['owner_id', 'warehouse_id', 'shop_id', 'logistic_id', 'date_target'])->get(); } private function getCreateByDatabaseUnitWeek($targetOwnerIdsUnderDates) { $orderSqlBuilder = Order::query()->selectRaw("owner_id,warehouse_id,shop_id,logistic_id,count(1) as amounts ,DATE_FORMAT(created_at,'%x-%v') as date_target"); foreach ($targetOwnerIdsUnderDates as $dateStr => $ownerIds) { $orderSqlBuilder->orWhere(function ($query) use ($ownerIds, $dateStr) { $dateStr = (new DateTime())->setISODate(Str::of($dateStr)->explode('-')[0], Str::of($dateStr)->explode('-')[1])->format('yy-m-d'); $query->whereIn('owner_id', $ownerIds)->where('created_at', '>', $dateStr)->where('created_at', '<=', Carbon::parse($dateStr)->addWeek()->toDateString())->where('wms_status', '订单完成'); }); } return $orderSqlBuilder->groupBy(['owner_id', 'warehouse_id', 'shop_id', 'logistic_id', 'date_target'])->get(); } private function getCreateByDatabaseUnitMonth($targetOwnerIdsUnderDates) { $orderSqlBuilder = Order::query()->selectRaw("owner_id,warehouse_id,shop_id,logistic_id,count(1) as amounts ,DATE_FORMAT(created_at,'%Y-%m') as date_target"); foreach ($targetOwnerIdsUnderDates as $dateStr => $ownerIds) { $orderSqlBuilder->orWhere(function ($query) use ($ownerIds, $dateStr) { $year = Str::of($dateStr)->explode('-')[0]; $month = Str::of($dateStr)->explode('-')[1]; $dateStr = $year . '-' . $month . '-01'; $query->whereIn('owner_id', $ownerIds)->where('created_at', '>', $dateStr)->where('created_at', '<', Carbon::parse($dateStr)->addMonth()->toDateString())->where('wms_status', '订单完成'); }); } return $orderSqlBuilder->groupBy(['owner_id', 'warehouse_id', 'shop_id', 'logistic_id', 'date_target'])->get(); } /** * @param $dateStr * @return bool */ public function isNotCurrentDate($dateStr): bool { return $dateStr != Carbon::now()->format('Y-m-d') && $dateStr != Carbon::now()->year . '-' . Carbon::now()->week && $dateStr != Carbon::now()->year . '-' . Carbon::now()->month; } }