package com.ffii.fpsms.modules.usage; import java.util.HashMap; import java.util.List; import java.util.Map; import java.time.LocalDate; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import com.ffii.core.support.AbstractService; import com.ffii.core.support.JdbcDao; import com.ffii.fpsms.modules.user.entity.User; @Service public class FeatureUsageLogService extends AbstractService { public static final String FEATURE_REPORT_MANAGEMENT = "REPORT_MANAGEMENT"; public static final String FEATURE_TRUCK_ROUTING_SUMMARY = "TRUCK_ROUTING_SUMMARY"; public static final String ACTION_PAGE_VIEW = "PAGE_VIEW"; public static final String ACTION_DOWNLOAD = "DOWNLOAD"; public static final String ACTION_PRINT = "PRINT"; public FeatureUsageLogService(JdbcDao jdbcDao) { super(jdbcDao); } @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = false) public void insert(User user, String featureCode, String actionType, String detail) { String sql = "INSERT INTO feature_usage_log (`user_id`, `username`, `feature_code`, `action_type`, `detail`) " + "VALUES (:userId, :username, :featureCode, :actionType, :detail)"; Map args = new HashMap<>(8); args.put("userId", user.getId()); args.put("username", user.getUsername()); args.put("featureCode", featureCode); args.put("actionType", actionType); args.put("detail", StringUtils.isBlank(detail) ? null : StringUtils.left(detail, 512)); jdbcDao.executeUpdate(sql, args); } @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true) public List> summarizeByFeature(String featureCode, LocalDate startDate, LocalDate endDate) { StringBuilder sql = new StringBuilder(""" SELECT user_id AS userId, username, SUM(CASE WHEN action_type = 'PAGE_VIEW' THEN 1 ELSE 0 END) AS pageViews, SUM(CASE WHEN action_type = 'DOWNLOAD' THEN 1 ELSE 0 END) AS downloads, SUM(CASE WHEN action_type = 'PRINT' THEN 1 ELSE 0 END) AS prints FROM feature_usage_log WHERE feature_code = :featureCode """); Map args = new HashMap<>(4); args.put("featureCode", featureCode); if (startDate != null) { sql.append(" AND created_at >= :startDate"); args.put("startDate", startDate.atStartOfDay()); } if (endDate != null) { sql.append(" AND created_at < :endDateExclusive"); args.put("endDateExclusive", endDate.plusDays(1).atStartOfDay()); } sql.append(""" GROUP BY user_id, username ORDER BY username """); return jdbcDao.queryForList(sql.toString(), args); } }