perf: 优化签到数据

This commit is contained in:
kuaifan 2022-12-13 19:05:06 +08:00
parent 4ff23148e6
commit 090ce1cf18
3 changed files with 53 additions and 15 deletions

View File

@ -864,7 +864,7 @@ class SystemController extends AbstractController
$users = User::whereIn('userid', $userid)->take(20)->get();
/** @var User $user */
foreach ($users as $user) {
$records = UserCheckinRecord::whereUserid($user->userid)->whereBetween("created_at", [$startD, $endD])->orderBy('id')->get()->keyBy('date');
$recordTimes = UserCheckinRecord::getTimes($user->userid, [$startD, $endD]);
//
$nickname = Base::filterEmoji($user->nickname);
$styles = ["A1:H1" => ["font" => ["bold" => true]]];
@ -875,8 +875,8 @@ class SystemController extends AbstractController
while ($startT < $endT) {
$index++;
$sameDate = date("Y-m-d", $startT);
$sameRecord = isset($records[$sameDate]) ? $records[$sameDate] : null;
$sameCollect = $sameRecord?->atCollect();
$sameTimes = $recordTimes[$sameDate] ?? [];
$sameCollect = UserCheckinRecord::atCollect($sameDate, $sameTimes);
$firstBetween = [Carbon::createFromTimestamp($startT), Carbon::createFromTimestamp($startT + $secondEnd - 1)];
$lastBetween = [Carbon::createFromTimestamp($startT + $secondStart + 1), Carbon::createFromTimestamp($startT + 86400)];
$firstRecord = $sameCollect?->whereBetween("datetime", $firstBetween)->first();
@ -912,7 +912,7 @@ class SystemController extends AbstractController
$lastTimestamp = $lastTimestamp ? date("H:i", $lastTimestamp) : "-";
$section = array_map(function($item) {
return $item[0] . "-" . ($item[1] ?: "None");
}, $sameRecord?->atSection() ?: []);
}, UserCheckinRecord::atSection($sameTimes));
$datas[] = [
"{$nickname} (ID: {$user->userid})",
$sameDate,

View File

@ -1412,17 +1412,17 @@ class UsersController extends AbstractController
$start = Carbon::parse(date("Y-m-01 00:00:00", strtotime($ym)));
$end = (clone $start)->addMonth()->subSecond();
//
$records = UserCheckinRecord::whereUserid($user->userid)->whereBetween('created_at', [$start, $end])->orderBy('id')->get()->keyBy('date');
$recordTimes = UserCheckinRecord::getTimes($user->userid, [$start, $end]);
$array = [];
$startT = $start->timestamp;
$endT = $end->timestamp;
while ($startT < $endT) {
$sameDate = date("Y-m-d", $startT);
$sameRecord = isset($records[$sameDate]) ? $records[$sameDate] : null;
if ($sameRecord) {
$sameTimes = $recordTimes[$sameDate] ?? [];
if ($sameTimes) {
$array[] = [
'date' => $sameDate,
'section' => $sameRecord->atSection(),
'section' => UserCheckinRecord::atSection($sameTimes),
];
}
$startT += 86400;

View File

@ -45,32 +45,70 @@ class UserCheckinRecord extends AbstractModel
return Base::json2array($value);
}
/**
* 获取签到时间
* @param int $userid
* @param array $betweenTimes
* @return array
*/
public static function getTimes(int $userid, array $betweenTimes)
{
$array = [];
$records = self::whereUserid($userid)->whereBetween('created_at', $betweenTimes)->orderBy('id')->get();
/** @var self $record */
foreach ($records as $record) {
$times = array_map(function ($time) {
return preg_replace("/(\d+):(\d+):\d+$/", "$1:$2", $time);
}, $record->times);
if (isset($array[$record->date])) {
$array[$record->date] = array_merge($array[$record->date], $times);
} else {
$array[$record->date] = $times;
}
}
//
foreach ($array as $date => $times) {
$times = array_values(array_filter(array_unique($times)));
$inOrder = [];
foreach ($times as $key => $time) {
$inOrder[$key] = strtotime("2022-01-01 {$time}");
}
array_multisort($inOrder, SORT_ASC, $times);
$array[$date] = $times;
}
//
return $array;
}
/**
* 时间收集
* @param string $data
* @param array $times
* @return \Illuminate\Support\Collection
*/
public function atCollect()
public static function atCollect($data, $times)
{
$sameTimes = array_map(function($time) {
$sameTimes = array_map(function($time) use ($data) {
return [
"datetime" => "{$this->date} {$time}",
"timestamp" => strtotime("{$this->date} {$time}")
"datetime" => "{$data} {$time}",
"timestamp" => strtotime("{$data} {$time}")
];
}, $this->times);
}, $times);
return collect($sameTimes);
}
/**
* 签到时段
* @param array $times
* @param int $diff 多长未签到算失效(秒)
* @return array
*/
public function atSection($diff = 3600)
public static function atSection($times, $diff = 3600)
{
$start = "";
$end = "";
$array = [];
foreach ($this->times as $time) {
foreach ($times as $time) {
$time = preg_replace("/(\d+):(\d+):\d+$/", "$1:$2", $time);
if (empty($start)) {
$start = $time;