| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- <?php
- namespace App\Services;
- use App\Order;
- use App\OrderCountingRecord;
- use Carbon\Carbon;
- use Illuminate\Support\Arr;
- use Illuminate\Support\Facades\Cache;
- class NewOrderCountingRecordService
- {
- public function orderCountingRecords($start, $end, $unit)
- {
- $key = 'orderCountingRecords_' . $start . '_' . $end . '_' . $unit . '_' . auth()->id();
- return \cache()->remember($key, 600, function () use ($start, $end, $unit) {
- $result = collect();
- switch ($unit) {
- case '日':
- $result = $this->orderCountingRecordsDay($start, $end, $unit);
- break;
- case '周':
- $result = $this->orderCountingRecordsWeek($start, $end, $unit);
- break;
- case '月':
- $result = $this->orderCountingRecordsMonth($start, $end, $unit);
- break;
- case '年':
- $result = $this->orderCountingRecordsYear($start, $end, $unit);
- break;
- default:
- break;
- }
- return $result;
- });
- }
- public function getCountingOwnerIds($ownerIds = null): array
- {
- $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);
- });
- }
- public function dataFromCache($start, $end, $unit)
- {
- $result = [];
- $unQueryCondition = [];
- $dataFromCache = collect();
- $queryCondition = $this->dateUtils($start, $end, $unit);
- foreach ($queryCondition as $dateStr => $ownerIds) {
- foreach ($ownerIds as $ownerId) {
- $key = 'order_counting_records_' . $dateStr . '_' . $ownerId . '_' . $unit . '_' . auth()->id();
- $items = cache()->get($key);
- if (empty($items)) {
- if (empty($unQueryCondition[$dateStr])) $unQueryCondition[$dateStr] = [];
- $unQueryCondition[$dateStr][] = $ownerId;
- } else {
- $dataFromCache = $dataFromCache->concat($items);
- }
- }
- }
- $result['dataFromCache'] = $dataFromCache;
- $result['unQueryCondition'] = $unQueryCondition;
- return $result;
- }
- public function dataFromMiddleTable($unQueryCondition, $unit)
- {
- $result = [];
- $orderSqlBuilder = OrderCountingRecord::query();
- foreach ($unQueryCondition as $date => $owners) {
- $orderSqlBuilder->orWhere(function ($query) use ($owners, $date, $unit) {
- $query->whereIn('owner_id', $owners)->where('date_target', $date)->where('counting_unit', $unit);
- });
- }
- $dataFromMiddleTable = $orderSqlBuilder->get();
- $this->insertIntoCache($dataFromMiddleTable, $unit);
- $unQueryCondition = $this->unQueryCondition($dataFromMiddleTable, $unQueryCondition);
- $result['unQueryCondition'] = $unQueryCondition;
- $result['dataFromMiddleTable'] = $dataFromMiddleTable;
- return $result;
- }
- public function orderCountingRecordsDay($start, $end, $unit)
- {
- $dataFromCacheResult = $this->dataFromCache($start, $end, $unit);
- $dataFromCache = $dataFromCacheResult['dataFromCache'];
- $unQueryCondition = $dataFromCacheResult['unQueryCondition'];
- if (!empty($unQueryCondition)) {
- $dataFromMiddleTableResult = $this->dataFromMiddleTable($unQueryCondition, $unit);
- $dataFromMiddleTable = $dataFromMiddleTableResult['dataFromMiddleTable'];
- $unQueryCondition = $dataFromMiddleTableResult['unQueryCondition'];
- if (!empty($unQueryCondition)) {
- $dataFromOrder = $this->dataFromOrder($unQueryCondition, $unit);
- }
- }
- $dataFromCache = $dataFromCache ?? collect();
- $dataFromMiddleTable = $dataFromMiddleTable ?? collect();
- $dataFromOrder = $dataFromOrder ?? collect();
- return $dataFromCache->concat($dataFromMiddleTable)->concat($dataFromOrder);
- }
- public function dateUtils($start, $end, $unit)
- {
- $ownerIds = $this->getCountingOwnerIds();
- $dataArray = [];
- switch ($unit) {
- case '日';
- foreach (Carbon::parse($start)->daysUntil($end, 1)->toArray() as $item) {
- $dataArray[$item->toDateString()] = $ownerIds;
- }
- break;
- case '周';
- foreach (Carbon::parse($start)->weeksUntil($end, 1)->toArray() as $item) {
- $dataArray[$item->year . '-' . $item->week . ''] = $ownerIds;
- }
- break;
- case '月';
- foreach (Carbon::parse($start)->monthsUntil($end, 1)->toArray() as $item) {
- $dataArray[$item->year . '-' . $item->format('m') . ''] = $ownerIds;
- }
- break;
- case '年';
- foreach (Carbon::parse($start)->yearsUntil($end, 1)->toArray() as $item) {
- $dataArray[$item->year] = $ownerIds;
- }
- break;
- default:
- break;
- }
- return $dataArray;
- }
- public function dataFromOrder($unQueryCondition, $unit)
- {
- $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 ($unQueryCondition 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', '订单完成');
- });
- }
- $dataFromOrder = $orderSqlBuilder->groupBy(['owner_id', 'warehouse_id', 'shop_id', 'logistic_id', 'date_target'])->get();
- $dataFromMiddleTable = $this->ordersToOrderCountingRecords($dataFromOrder);
- $this->insertIntoMiddleTable($dataFromMiddleTable, $unit);
- $this->insertIntoCache($dataFromMiddleTable, $unit);
- return $dataFromMiddleTable;
- }
- public function orderCountingRecordsWeek($start, $end, $unit)
- {
- //TODO
- return collect();
- }
- public function orderCountingRecordsMonth($start, $end, $unit)
- {
- //TODO
- return collect();
- }
- public function orderCountingRecordsYear($start, $end, $unit)
- {
- //TODO
- return collect();
- }
- public function insertIntoMiddleTable($data, $unit)
- {
- $data->filter(function ($item) {
- return $this->isNotCurrentDate($item->date_target);
- })->chunk(1000)->each(function ($item) {
- OrderCountingRecord::query()->insert($item->toArray());
- });
- }
- public function insertIntoCache($collect, $unit)
- {
- $map = [];
- $collect->each(function ($order) use ($unit, &$map) {
- $key = "order_counting_records_{$order->date_target}_{$order->owner_id}_{$unit}";
- if (empty($map[$key])) $map[$key] = [];
- $map[$key][] = $order;
- });
- foreach ($map as $key => $orders) {
- $ttl = 3600 * 24;
- if (!$this->isNotCurrentDate($orders[0]['date_target'])) {
- $ttl = 70;
- }
- Cache::put($key, collect($orders), $ttl);
- }
- }
- 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;
- }
- public function unQueryCondition($dataFromMiddleTable, $unQueryCondition)
- {
- $map = [];
- $dataFromMiddleTable->each(function ($item) use (&$map) {
- $key = 'owner_id=' . $item->owner_id . ' date_target' . $item->date_target;
- $map[$key] = true;
- });
- foreach ($unQueryCondition as $dateStr => $ownerIds) {
- foreach ($ownerIds as $key => $ownerId) {
- $key1 = 'owner_id=' . $ownerId . ' date_target' . $dateStr;
- if (isset($map[$key1])) {
- //中间表查找到数据
- unset($unQueryCondition[$dateStr][$key]);
- }
- }
- }
- return $unQueryCondition;
- }
- public function ordersToOrderCountingRecords($dataFromOrder)
- {
- $dataFromMiddleTable = collect();
- //当日当周当月当年的数据不能插入到中间表
- $dateTime = Carbon::now()->toDateTimeString();
- foreach ($dataFromOrder as $order) {
- $dataFromMiddleTable->push(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' => $order->counting_unit,
- 'amount' => $order->amounts,
- 'created_at' => $dateTime,
- 'updated_at' => $dateTime,
- ]));
- }
- return $dataFromMiddleTable;
- }
- }
|