|
@@ -492,9 +492,9 @@ class User extends Controller
|
|
|
/**
|
|
/**
|
|
|
* 用户登录日志
|
|
* 用户登录日志
|
|
|
*
|
|
*
|
|
|
- * 返回字段:user_id/member_id、first_name、login_ip、country(国家/地区)、
|
|
|
|
|
- * browser(浏览器)、os(操作系统)、status/status_text(登录成功或失败)、
|
|
|
|
|
- * created_at(登录时间)、logout_time(登出时间)、online_duration(在线时长分钟)
|
|
|
|
|
|
|
+ * 字段:user_id、login_account、login_ip、country、browser、os、
|
|
|
|
|
+ * status/status_text、created_at、logout_time、online_duration(登出后落库)、
|
|
|
|
|
+ * is_online、online_duration_live(未登出时估算分钟数)
|
|
|
*/
|
|
*/
|
|
|
public function loginLog()
|
|
public function loginLog()
|
|
|
{
|
|
{
|
|
@@ -509,15 +509,15 @@ class User extends Controller
|
|
|
'start_time' => ['nullable', 'date', 'date_format:Y-m-d', 'required_with:end_time'],
|
|
'start_time' => ['nullable', 'date', 'date_format:Y-m-d', 'required_with:end_time'],
|
|
|
'end_time' => ['nullable', 'date', 'date_format:Y-m-d', 'required_with:start_time'],
|
|
'end_time' => ['nullable', 'date', 'date_format:Y-m-d', 'required_with:start_time'],
|
|
|
]);
|
|
]);
|
|
|
- $page = request()->input('page', 1);
|
|
|
|
|
- $limit = request()->input('limit', 15);
|
|
|
|
|
|
|
+ $page = (int)request()->input('page', 1);
|
|
|
|
|
+ $limit = (int)request()->input('limit', 15);
|
|
|
|
|
|
|
|
- // leftJoin:失败日志也可能没有对应用户,仍需展示日志本身
|
|
|
|
|
$query = UserLogin::query()
|
|
$query = UserLogin::query()
|
|
|
->leftJoin('users', 'user_login.user_id', '=', 'users.user_id')
|
|
->leftJoin('users', 'user_login.user_id', '=', 'users.user_id')
|
|
|
->select([
|
|
->select([
|
|
|
'user_login.id',
|
|
'user_login.id',
|
|
|
'user_login.user_id',
|
|
'user_login.user_id',
|
|
|
|
|
+ 'user_login.login_account',
|
|
|
'user_login.login_ip',
|
|
'user_login.login_ip',
|
|
|
'user_login.country',
|
|
'user_login.country',
|
|
|
'user_login.browser',
|
|
'user_login.browser',
|
|
@@ -543,46 +543,25 @@ class User extends Controller
|
|
|
if (!empty($params['first_name'])) {
|
|
if (!empty($params['first_name'])) {
|
|
|
$query->where('users.first_name', 'like', "%{$params['first_name']}%");
|
|
$query->where('users.first_name', 'like', "%{$params['first_name']}%");
|
|
|
}
|
|
}
|
|
|
- if (isset($params['status']) && $params['status'] !== '' && $params['status'] !== null) {
|
|
|
|
|
|
|
+ if (array_key_exists('status', $params) && $params['status'] !== null) {
|
|
|
$query->where('user_login.status', (int)$params['status']);
|
|
$query->where('user_login.status', (int)$params['status']);
|
|
|
}
|
|
}
|
|
|
if (!empty($params['start_time'])) {
|
|
if (!empty($params['start_time'])) {
|
|
|
- $startTime = $params['start_time'] . " 00:00:00";
|
|
|
|
|
- $query->where('user_login.created_at', '>=', $startTime);
|
|
|
|
|
|
|
+ $query->where('user_login.created_at', '>=', $params['start_time'] . ' 00:00:00');
|
|
|
}
|
|
}
|
|
|
if (!empty($params['end_time'])) {
|
|
if (!empty($params['end_time'])) {
|
|
|
- $endTime = $params['end_time'] . " 23:59:59";
|
|
|
|
|
- $query->where('user_login.created_at', '<=', $endTime);
|
|
|
|
|
|
|
+ $query->where('user_login.created_at', '<=', $params['end_time'] . ' 23:59:59');
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
$count = (clone $query)->count();
|
|
$count = (clone $query)->count();
|
|
|
$list = $query
|
|
$list = $query
|
|
|
->forPage($page, $limit)
|
|
->forPage($page, $limit)
|
|
|
->orderByDesc('user_login.id')
|
|
->orderByDesc('user_login.id')
|
|
|
- ->get()
|
|
|
|
|
- ->map(function ($item) {
|
|
|
|
|
- // 未登出时:若仍在线可按当前时间估算在线时长(仅展示,不写库)
|
|
|
|
|
- if (
|
|
|
|
|
- (int)$item->status === UserLogin::STATUS_SUCCESS
|
|
|
|
|
- && empty($item->getRawOriginal('logout_time'))
|
|
|
|
|
- && empty($item->online_duration)
|
|
|
|
|
- && !empty($item->getRawOriginal('created_at'))
|
|
|
|
|
- ) {
|
|
|
|
|
- $loginAt = strtotime($item->getRawOriginal('created_at'));
|
|
|
|
|
- if ($loginAt) {
|
|
|
|
|
- $item->online_duration = (int)ceil(max(0, time() - $loginAt) / 60);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- // 国家/地区等空值统一给前端可展示的占位
|
|
|
|
|
- $item->country = $item->country ?: '';
|
|
|
|
|
- $item->browser = $item->browser ?: '';
|
|
|
|
|
- $item->os = $item->os ?: '';
|
|
|
|
|
- return $item;
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ ->get();
|
|
|
} catch (Exception $e) {
|
|
} catch (Exception $e) {
|
|
|
- return $this->error(HttpStatus::CUSTOM_ERROR,$e->getMessage());
|
|
|
|
|
|
|
+ return $this->error(HttpStatus::CUSTOM_ERROR, $e->getMessage());
|
|
|
}
|
|
}
|
|
|
return $this->success(['total' => $count, 'data' => $list]);
|
|
return $this->success(['total' => $count, 'data' => $list]);
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function setRechargeChannelGroup()
|
|
function setRechargeChannelGroup()
|