Files
2025-11-17 14:11:46 +08:00

405 lines
11 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}