405 lines
11 KiB
Go
405 lines
11 KiB
Go
package service
|
||
|
||
import (
|
||
"dianshang/internal/model"
|
||
"time"
|
||
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// LogService 日志服务
|
||
type LogService struct {
|
||
db *gorm.DB
|
||
}
|
||
|
||
// NewLogService 创建日志服务
|
||
func NewLogService(db *gorm.DB) *LogService {
|
||
return &LogService{
|
||
db: db,
|
||
}
|
||
}
|
||
|
||
// CreateLoginLog 创建登录日志
|
||
func (s *LogService) CreateLoginLog(userID uint, ip, userAgent string, status int, remark string) error {
|
||
log := &model.UserLoginLog{
|
||
UserID: userID,
|
||
LoginIP: ip,
|
||
UserAgent: userAgent,
|
||
LoginTime: time.Now(),
|
||
Status: status,
|
||
Remark: remark,
|
||
}
|
||
return s.db.Create(log).Error
|
||
}
|
||
|
||
// GetUserLoginLogs 获取用户登录日志
|
||
func (s *LogService) GetUserLoginLogs(userID uint, page, pageSize int) ([]model.UserLoginLog, map[string]interface{}, error) {
|
||
var logs []model.UserLoginLog
|
||
var total int64
|
||
|
||
query := s.db.Model(&model.UserLoginLog{}).Where("user_id = ?", userID)
|
||
|
||
// 获取总数
|
||
err := query.Count(&total).Error
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
|
||
// 分页查询
|
||
offset := (page - 1) * pageSize
|
||
err = query.Offset(offset).Limit(pageSize).Order("login_time DESC").Find(&logs).Error
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
|
||
// 构建分页信息
|
||
pagination := map[string]interface{}{
|
||
"total": total,
|
||
"page": page,
|
||
"page_size": pageSize,
|
||
"total_pages": (total + int64(pageSize) - 1) / int64(pageSize),
|
||
}
|
||
|
||
return logs, pagination, nil
|
||
}
|
||
|
||
// GetLoginLogList 获取登录日志列表(管理后台)
|
||
func (s *LogService) GetLoginLogList(page, pageSize int, conditions map[string]interface{}) ([]model.UserLoginLog, map[string]interface{}, error) {
|
||
var logs []model.UserLoginLog
|
||
var total int64
|
||
|
||
query := s.db.Model(&model.UserLoginLog{}).Preload("User")
|
||
|
||
// 应用查询条件
|
||
if userID, ok := conditions["user_id"]; ok && userID != "" {
|
||
query = query.Where("user_id = ?", userID)
|
||
}
|
||
|
||
if ip, ok := conditions["ip"]; ok && ip != "" {
|
||
query = query.Where("login_ip LIKE ?", "%"+ip.(string)+"%")
|
||
}
|
||
|
||
if status, ok := conditions["status"]; ok && status != "" {
|
||
query = query.Where("status = ?", status)
|
||
}
|
||
|
||
if startDate, ok := conditions["start_date"]; ok && startDate != "" {
|
||
query = query.Where("login_time >= ?", startDate)
|
||
}
|
||
|
||
if endDate, ok := conditions["end_date"]; ok && endDate != "" {
|
||
query = query.Where("login_time <= ?", endDate)
|
||
}
|
||
|
||
// 获取总数
|
||
err := query.Count(&total).Error
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
|
||
// 分页查询
|
||
offset := (page - 1) * pageSize
|
||
err = query.Offset(offset).Limit(pageSize).Order("login_time DESC").Find(&logs).Error
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
|
||
// 构建分页信息
|
||
pagination := map[string]interface{}{
|
||
"total": total,
|
||
"page": page,
|
||
"page_size": pageSize,
|
||
"total_pages": (total + int64(pageSize) - 1) / int64(pageSize),
|
||
}
|
||
|
||
return logs, pagination, nil
|
||
}
|
||
|
||
// CreateOperationLog 创建操作日志
|
||
func (s *LogService) CreateOperationLog(userID uint, module, action, description, ip, userAgent, requestData string) error {
|
||
log := &model.UserOperationLog{
|
||
UserID: userID,
|
||
Module: module,
|
||
Action: action,
|
||
Description: description,
|
||
IP: ip,
|
||
UserAgent: userAgent,
|
||
RequestData: requestData,
|
||
CreatedAt: time.Now(),
|
||
}
|
||
return s.db.Create(log).Error
|
||
}
|
||
|
||
// GetUserOperationLogs 获取用户操作日志
|
||
func (s *LogService) GetUserOperationLogs(userID uint, page, pageSize int) ([]model.UserOperationLog, map[string]interface{}, error) {
|
||
var logs []model.UserOperationLog
|
||
var total int64
|
||
|
||
query := s.db.Model(&model.UserOperationLog{}).Where("user_id = ?", userID)
|
||
|
||
// 获取总数
|
||
err := query.Count(&total).Error
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
|
||
// 分页查询
|
||
offset := (page - 1) * pageSize
|
||
err = query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&logs).Error
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
|
||
// 构建分页信息
|
||
pagination := map[string]interface{}{
|
||
"total": total,
|
||
"page": page,
|
||
"page_size": pageSize,
|
||
"total_pages": (total + int64(pageSize) - 1) / int64(pageSize),
|
||
}
|
||
|
||
return logs, pagination, nil
|
||
}
|
||
|
||
// GetOperationLogList 获取操作日志列表(管理后台)
|
||
func (s *LogService) GetOperationLogList(page, pageSize int, conditions map[string]interface{}) ([]model.UserOperationLog, map[string]interface{}, error) {
|
||
var logs []model.UserOperationLog
|
||
var total int64
|
||
|
||
query := s.db.Model(&model.UserOperationLog{}).Preload("User")
|
||
|
||
// 应用查询条件
|
||
if userID, ok := conditions["user_id"]; ok && userID != "" {
|
||
query = query.Where("user_id = ?", userID)
|
||
}
|
||
|
||
if module, ok := conditions["module"]; ok && module != "" {
|
||
query = query.Where("module = ?", module)
|
||
}
|
||
|
||
if action, ok := conditions["action"]; ok && action != "" {
|
||
query = query.Where("action = ?", action)
|
||
}
|
||
|
||
if ip, ok := conditions["ip"]; ok && ip != "" {
|
||
query = query.Where("ip LIKE ?", "%"+ip.(string)+"%")
|
||
}
|
||
|
||
if startDate, ok := conditions["start_date"]; ok && startDate != "" {
|
||
query = query.Where("created_at >= ?", startDate)
|
||
}
|
||
|
||
if endDate, ok := conditions["end_date"]; ok && endDate != "" {
|
||
query = query.Where("created_at <= ?", endDate)
|
||
}
|
||
|
||
// 获取总数
|
||
err := query.Count(&total).Error
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
|
||
// 分页查询
|
||
offset := (page - 1) * pageSize
|
||
err = query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&logs).Error
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
|
||
// 构建分页信息
|
||
pagination := map[string]interface{}{
|
||
"total": total,
|
||
"page": page,
|
||
"page_size": pageSize,
|
||
"total_pages": (total + int64(pageSize) - 1) / int64(pageSize),
|
||
}
|
||
|
||
return logs, pagination, nil
|
||
}
|
||
|
||
// GetLoginStatistics 获取登录统计
|
||
func (s *LogService) GetLoginStatistics(startDate, endDate string) (map[string]interface{}, error) {
|
||
result := make(map[string]interface{})
|
||
|
||
// 总登录次数
|
||
var totalLogins int64
|
||
query := s.db.Model(&model.UserLoginLog{})
|
||
if startDate != "" && endDate != "" {
|
||
query = query.Where("DATE(login_time) BETWEEN ? AND ?", startDate, endDate)
|
||
}
|
||
query.Count(&totalLogins)
|
||
result["total_logins"] = totalLogins
|
||
|
||
// 成功登录次数
|
||
var successLogins int64
|
||
query = s.db.Model(&model.UserLoginLog{}).Where("status = 1")
|
||
if startDate != "" && endDate != "" {
|
||
query = query.Where("DATE(login_time) BETWEEN ? AND ?", startDate, endDate)
|
||
}
|
||
query.Count(&successLogins)
|
||
result["success_logins"] = successLogins
|
||
|
||
// 失败登录次数
|
||
var failedLogins int64
|
||
query = s.db.Model(&model.UserLoginLog{}).Where("status = 0")
|
||
if startDate != "" && endDate != "" {
|
||
query = query.Where("DATE(login_time) BETWEEN ? AND ?", startDate, endDate)
|
||
}
|
||
query.Count(&failedLogins)
|
||
result["failed_logins"] = failedLogins
|
||
|
||
// 独立用户数
|
||
var uniqueUsers int64
|
||
query = s.db.Model(&model.UserLoginLog{}).Distinct("user_id")
|
||
if startDate != "" && endDate != "" {
|
||
query = query.Where("DATE(login_time) BETWEEN ? AND ?", startDate, endDate)
|
||
}
|
||
query.Count(&uniqueUsers)
|
||
result["unique_users"] = uniqueUsers
|
||
|
||
return result, nil
|
||
}
|
||
|
||
// GetOperationStatistics 获取操作统计
|
||
func (s *LogService) GetOperationStatistics(startDate, endDate string) (map[string]interface{}, error) {
|
||
result := make(map[string]interface{})
|
||
|
||
// 总操作次数
|
||
var totalOperations int64
|
||
query := s.db.Model(&model.UserOperationLog{})
|
||
if startDate != "" && endDate != "" {
|
||
query = query.Where("DATE(created_at) BETWEEN ? AND ?", startDate, endDate)
|
||
}
|
||
query.Count(&totalOperations)
|
||
result["total_operations"] = totalOperations
|
||
|
||
// 按模块统计
|
||
var moduleStats []struct {
|
||
Module string `json:"module"`
|
||
Count int64 `json:"count"`
|
||
}
|
||
query = s.db.Model(&model.UserOperationLog{}).Select("module, COUNT(*) as count").Group("module")
|
||
if startDate != "" && endDate != "" {
|
||
query = query.Where("DATE(created_at) BETWEEN ? AND ?", startDate, endDate)
|
||
}
|
||
query.Scan(&moduleStats)
|
||
result["module_stats"] = moduleStats
|
||
|
||
// 按操作统计
|
||
var actionStats []struct {
|
||
Action string `json:"action"`
|
||
Count int64 `json:"count"`
|
||
}
|
||
query = s.db.Model(&model.UserOperationLog{}).Select("action, COUNT(*) as count").Group("action")
|
||
if startDate != "" && endDate != "" {
|
||
query = query.Where("DATE(created_at) BETWEEN ? AND ?", startDate, endDate)
|
||
}
|
||
query.Scan(&actionStats)
|
||
result["action_stats"] = actionStats
|
||
|
||
return result, nil
|
||
}
|
||
|
||
// CleanOldLogs 清理旧日志
|
||
func (s *LogService) CleanOldLogs(days int) error {
|
||
cutoffDate := time.Now().AddDate(0, 0, -days)
|
||
|
||
// 清理登录日志
|
||
if err := s.db.Where("login_time < ?", cutoffDate).Delete(&model.UserLoginLog{}).Error; err != nil {
|
||
return err
|
||
}
|
||
|
||
// 清理操作日志
|
||
if err := s.db.Where("created_at < ?", cutoffDate).Delete(&model.UserOperationLog{}).Error; err != nil {
|
||
return err
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// GetLoginLogByID 根据ID获取登录日志
|
||
func (s *LogService) GetLoginLogByID(id uint) (*model.UserLoginLog, error) {
|
||
var log model.UserLoginLog
|
||
err := s.db.Preload("User").First(&log, id).Error
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return &log, nil
|
||
}
|
||
|
||
// GetTodayLoginCount 获取今日登录次数
|
||
func (s *LogService) GetTodayLoginCount() (int64, error) {
|
||
var count int64
|
||
today := time.Now().Format("2006-01-02")
|
||
err := s.db.Model(&model.UserLoginLog{}).Where("DATE(login_time) = ?", today).Count(&count).Error
|
||
return count, err
|
||
}
|
||
|
||
// GetTodayOperationCount 获取今日操作次数
|
||
func (s *LogService) GetTodayOperationCount() (int64, error) {
|
||
var count int64
|
||
today := time.Now().Format("2006-01-02")
|
||
err := s.db.Model(&model.UserOperationLog{}).Where("DATE(created_at) = ?", today).Count(&count).Error
|
||
return count, err
|
||
}
|
||
|
||
// GetOnlineUserCount 获取在线用户数(最近30分钟有登录记录的用户)
|
||
func (s *LogService) GetOnlineUserCount() (int64, error) {
|
||
var count int64
|
||
thirtyMinutesAgo := time.Now().Add(-30 * time.Minute)
|
||
err := s.db.Model(&model.UserLoginLog{}).
|
||
Where("login_time >= ? AND status = 1", thirtyMinutesAgo).
|
||
Distinct("user_id").
|
||
Count(&count).Error
|
||
return count, err
|
||
}
|
||
|
||
// GetLoginTrend 获取登录趋势
|
||
func (s *LogService) GetLoginTrend(days int) ([]map[string]interface{}, error) {
|
||
var results []map[string]interface{}
|
||
|
||
for i := days - 1; i >= 0; i-- {
|
||
date := time.Now().AddDate(0, 0, -i).Format("2006-01-02")
|
||
var count int64
|
||
s.db.Model(&model.UserLoginLog{}).
|
||
Where("DATE(login_time) = ?", date).
|
||
Count(&count)
|
||
|
||
results = append(results, map[string]interface{}{
|
||
"date": date,
|
||
"count": count,
|
||
})
|
||
}
|
||
|
||
return results, nil
|
||
}
|
||
|
||
// GetOperationTrend 获取操作趋势
|
||
func (s *LogService) GetOperationTrend(days int) ([]map[string]interface{}, error) {
|
||
var results []map[string]interface{}
|
||
|
||
for i := days - 1; i >= 0; i-- {
|
||
date := time.Now().AddDate(0, 0, -i).Format("2006-01-02")
|
||
var count int64
|
||
s.db.Model(&model.UserOperationLog{}).
|
||
Where("DATE(created_at) = ?", date).
|
||
Count(&count)
|
||
|
||
results = append(results, map[string]interface{}{
|
||
"date": date,
|
||
"count": count,
|
||
})
|
||
}
|
||
|
||
return results, nil
|
||
}
|
||
|
||
// GetOperationLogByID 根据ID获取操作日志
|
||
func (s *LogService) GetOperationLogByID(id uint) (*model.UserOperationLog, error) {
|
||
var log model.UserOperationLog
|
||
err := s.db.Preload("User").First(&log, id).Error
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return &log, nil
|
||
} |