Files
ai_dianshang/server/internal/service/log.go

405 lines
11 KiB
Go
Raw Normal View History

2025-11-17 13:32:54 +08:00
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
}