From 858f515995fd1dca7cf825069ce38c32703298d0 Mon Sep 17 00:00:00 2001
From: peng <peng.com>
Date: 星期五, 07 十一月 2025 14:14:50 +0800
Subject: [PATCH] 报名人员导出

---
 backend/src/main/java/com/rongyichuang/player/service/PlayerApplicationService.java |  296 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 291 insertions(+), 5 deletions(-)

diff --git a/backend/src/main/java/com/rongyichuang/player/service/PlayerApplicationService.java b/backend/src/main/java/com/rongyichuang/player/service/PlayerApplicationService.java
index f78ffc1..fe813f9 100644
--- a/backend/src/main/java/com/rongyichuang/player/service/PlayerApplicationService.java
+++ b/backend/src/main/java/com/rongyichuang/player/service/PlayerApplicationService.java
@@ -1,10 +1,15 @@
 package com.rongyichuang.player.service;
 
+import com.rongyichuang.common.dto.PageResponse;
 import com.rongyichuang.player.dto.response.ActivityPlayerApplicationResponse;
 import jakarta.persistence.EntityManager;
 import jakarta.persistence.PersistenceContext;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.stereotype.Service;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -16,19 +21,37 @@
 
     /**
      * 鏌ヨ娲诲姩鎶ュ悕淇℃伅
+     * 鎶ュ悕瀹℃牳椤甸潰鍙樉绀烘捣閫夐樁娈电殑鏁版嵁锛屼笉鍖呭惈澶嶈禌绛夊悗缁樁娈�
+     * 褰撲紶鍏ctivityId鏃讹紝鏌ヨ璇ユ瘮璧涗笅绗竴涓樁娈碉紙sort_order=1锛夌殑鎶ュ悕椤圭洰
      */
     @SuppressWarnings("unchecked")
-    public List<ActivityPlayerApplicationResponse> listApplications(String name, Long activityId, Integer state, Integer page, Integer size) {
+    public PageResponse<ActivityPlayerApplicationResponse> listApplications(String name, Long activityId, Integer state, Integer page, Integer size) {
         String baseSql =
-            "SELECT ap.id, p.name AS player_name, a.name AS activity_name, ap.project_name AS project_name, p.phone AS phone, ap.create_time AS apply_time, ap.state AS state " +
+            "SELECT ap.id, p.name AS player_name, parent.name AS activity_name, ap.project_name AS project_name, u.phone AS phone, ap.create_time AS apply_time, ap.state AS state, " +
+            "COALESCE(rating_stats.rating_count, 0) AS rating_count, rating_stats.average_score " +
             "FROM t_activity_player ap " +
             "JOIN t_player p ON p.id = ap.player_id " +
-            "JOIN t_activity a ON a.id = ap.activity_id ";
+            "JOIN t_user u ON u.id = p.user_id " +
+            "JOIN t_activity stage ON stage.id = ap.stage_id " +
+            "JOIN t_activity parent ON parent.id = stage.pid " +
+            "LEFT JOIN (" +
+            "  SELECT activity_player_id, COUNT(*) AS rating_count, AVG(total_score) AS average_score " +
+            "  FROM t_activity_player_rating " +
+            "  WHERE state = 1 " +
+            "  GROUP BY activity_player_id" +
+            ") rating_stats ON rating_stats.activity_player_id = ap.id ";
         
         StringBuilder whereClause = new StringBuilder();
         boolean hasCondition = false;
         
+        // 榛樿鍙樉绀虹涓�闃舵鐨勬暟鎹紙鍩轰簬sort_order=1锛夛紝閬垮厤纭紪鐮侀樁娈靛悕绉�
+        whereClause.append("stage.sort_order = 1");
+        hasCondition = true;
+        
         if (name != null && !name.isEmpty()) {
+            if (hasCondition) {
+                whereClause.append(" AND ");
+            }
             whereClause.append("p.name LIKE CONCAT('%', :name, '%')");
             hasCondition = true;
         }
@@ -37,7 +60,8 @@
             if (hasCondition) {
                 whereClause.append(" AND ");
             }
-            whereClause.append("ap.stage_id = :activityId");
+            // 鏌ヨ鎸囧畾涓绘瘮璧涚殑绗竴闃舵鎶ュ悕椤圭洰锛歛ctivity_id=涓绘瘮璧汭D, stage_id=绗竴闃舵ID
+            whereClause.append("ap.activity_id = :activityId AND ap.stage_id = stage.id AND stage.pid = :activityId AND stage.sort_order = 1");
             hasCondition = true;
         }
         
@@ -64,6 +88,7 @@
         if (activityId != null) {
             q.setParameter("activityId", activityId);
         }
+
         if (state != null) {
             q.setParameter("state", state);
         }
@@ -79,8 +104,269 @@
             dto.setApplyTime(r[5] != null ? r[5].toString() : "");
             // 鏄犲皠鐘舵�侊細浣跨敤 t_activity_player.state锛�0=鏈鏍革紝1=瀹℃牳閫氳繃锛�2=瀹℃牳椹冲洖锛�
             dto.setState(r[6] != null ? Integer.valueOf(r[6].toString()) : 0);
+            // 鏄犲皠璇勫缁熻鏁版嵁
+            dto.setRatingCount(r[7] != null ? Integer.valueOf(r[7].toString()) : 0);
+            dto.setAverageScore(r[8] != null ? Double.valueOf(r[8].toString()) : null);
             list.add(dto);
         }
-        return list;
+        
+        // 鑾峰彇鎬绘暟
+        String countSql = "SELECT COUNT(*) " + baseSql.substring(baseSql.indexOf("FROM")) + where;
+        var countQuery = em.createNativeQuery(countSql);
+        if (name != null && !name.isEmpty()) {
+            countQuery.setParameter("name", name);
+        }
+        if (activityId != null) {
+            countQuery.setParameter("activityId", activityId);
+        }
+        if (state != null) {
+            countQuery.setParameter("state", state);
+        }
+        long total = ((Number) countQuery.getSingleResult()).longValue();
+        
+        return new PageResponse<>(list, total, page != null ? page : 1, size != null ? size : 10);
+    }
+
+    /**
+     * 瀵煎嚭娲诲姩鎶ュ悕淇℃伅涓篍xcel
+     */
+    @SuppressWarnings("unchecked")
+    public byte[] exportApplicationsToExcel(String name, Long activityId, Integer state) throws IOException {
+        String baseSql =
+            "SELECT ap.id, p.name AS player_name, parent.name AS activity_name, ap.project_name AS project_name, u.phone AS phone, ap.create_time AS apply_time, ap.state AS state, " +
+            "COALESCE(rating_stats.rating_count, 0) AS rating_count, rating_stats.average_score " +
+            "FROM t_activity_player ap " +
+            "JOIN t_player p ON p.id = ap.player_id " +
+            "JOIN t_user u ON u.id = p.user_id " +
+            "JOIN t_activity stage ON stage.id = ap.stage_id " +
+            "JOIN t_activity parent ON parent.id = stage.pid " +
+            "LEFT JOIN (" +
+            "  SELECT activity_player_id, COUNT(*) AS rating_count, AVG(total_score) AS average_score " +
+            "  FROM t_activity_player_rating " +
+            "  WHERE state = 1 " +
+            "  GROUP BY activity_player_id" +
+            ") rating_stats ON rating_stats.activity_player_id = ap.id ";
+        
+        StringBuilder whereClause = new StringBuilder();
+        boolean hasCondition = false;
+        
+        // 榛樿鍙樉绀虹涓�闃舵鐨勬暟鎹紙鍩轰簬sort_order=1锛夛紝閬垮厤纭紪鐮侀樁娈靛悕绉�
+        whereClause.append("stage.sort_order = 1");
+        hasCondition = true;
+        
+        if (name != null && !name.isEmpty()) {
+            if (hasCondition) {
+                whereClause.append(" AND ");
+            }
+            whereClause.append("p.name LIKE CONCAT('%', :name, '%')");
+            hasCondition = true;
+        }
+        
+        if (activityId != null) {
+            if (hasCondition) {
+                whereClause.append(" AND ");
+            }
+            // 鏌ヨ鎸囧畾涓绘瘮璧涚殑绗竴闃舵鎶ュ悕椤圭洰锛歛ctivity_id=涓绘瘮璧汭D, stage_id=绗竴闃舵ID
+            whereClause.append("ap.activity_id = :activityId AND ap.stage_id = stage.id AND stage.pid = :activityId AND stage.sort_order = 1");
+            hasCondition = true;
+        }
+        
+        if (state != null) {
+            if (hasCondition) {
+                whereClause.append(" AND ");
+            }
+            whereClause.append("ap.state = :state");
+            hasCondition = true;
+        }
+        
+        String where = hasCondition ? "WHERE " + whereClause.toString() + " " : "";
+        String order = "ORDER BY ap.create_time DESC ";
+
+        var q = em.createNativeQuery(baseSql + where + order);
+        if (name != null && !name.isEmpty()) {
+            q.setParameter("name", name);
+        }
+        if (activityId != null) {
+            q.setParameter("activityId", activityId);
+        }
+
+        if (state != null) {
+            q.setParameter("state", state);
+        }
+        List<Object[]> rows = q.getResultList();
+        
+        // 鍒涘缓Excel宸ヤ綔绨�
+        Workbook workbook = new XSSFWorkbook();
+        Sheet sheet = workbook.createSheet("鎶ュ悕浜哄憳");
+        
+        // 鍒涘缓鏍囬琛�
+        Row headerRow = sheet.createRow(0);
+        String[] headers = {"ID", "瀛﹀憳鍚嶇О", "姣旇禌鍚嶇О", "椤圭洰鍚嶇О", "鑱旂郴鐢佃瘽", "鐢宠鏃堕棿", "鐘舵��", "璇勫垎娆℃暟", "骞冲潎鍒�"};
+        for (int i = 0; i < headers.length; i++) {
+            Cell cell = headerRow.createCell(i);
+            cell.setCellValue(headers[i]);
+            
+            // 璁剧疆鏍囬鏍峰紡
+            CellStyle headerStyle = workbook.createCellStyle();
+            Font font = workbook.createFont();
+            font.setBold(true);
+            headerStyle.setFont(font);
+            cell.setCellStyle(headerStyle);
+        }
+        
+        // 濉厖鏁版嵁
+        int rowNum = 1;
+        for (Object[] r : rows) {
+            Row row = sheet.createRow(rowNum++);
+            row.createCell(0).setCellValue(r[0] != null ? r[0].toString() : "");
+            row.createCell(1).setCellValue(r[1] != null ? r[1].toString() : "");
+            row.createCell(2).setCellValue(r[2] != null ? r[2].toString() : "");
+            row.createCell(3).setCellValue(r[3] != null ? r[3].toString() : "");
+            row.createCell(4).setCellValue(r[4] != null ? r[4].toString() : "");
+            row.createCell(5).setCellValue(r[5] != null ? r[5].toString() : "");
+            
+            // 鐘舵�佽浆鎹�
+            String stateText = "鏈煡";
+            if (r[6] != null) {
+                int stateValue = Integer.parseInt(r[6].toString());
+                switch (stateValue) {
+                    case 0: stateText = "鏈鏍�"; break;
+                    case 1: stateText = "瀹℃牳閫氳繃"; break;
+                    case 2: stateText = "瀹℃牳椹冲洖"; break;
+                    default: stateText = "鏈煡";
+                }
+            }
+            row.createCell(6).setCellValue(stateText);
+            
+            row.createCell(7).setCellValue(r[7] != null ? r[7].toString() : "0");
+            row.createCell(8).setCellValue(r[8] != null ? r[8].toString() : "");
+        }
+        
+        // 鑷姩璋冩暣鍒楀
+        for (int i = 0; i < headers.length; i++) {
+            sheet.autoSizeColumn(i);
+        }
+        
+        // 灏嗗伐浣滅翱鍐欏叆瀛楄妭鏁扮粍
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        workbook.write(outputStream);
+        workbook.close();
+        outputStream.close();
+        
+        return outputStream.toByteArray();
+    }
+
+    /**
+     * 椤圭洰璇勫涓撶敤鏌ヨ锛屽寘鍚墍鏈夐樁娈垫暟鎹紙鍖呮嫭澶嶈禌銆佸喅璧涳級
+     * 涓巐istApplications鐨勫尯鍒細涓嶈繃婊ゅ璧涘拰鍐宠禌闃舵
+     */
+    @SuppressWarnings("unchecked")
+    public PageResponse<ActivityPlayerApplicationResponse> listProjectReviewApplications(String name, Long activityId, Long regionId, Integer state, Integer page, Integer size) {
+        String baseSql =
+            "SELECT ap.id, CONCAT(p.name, '锛�', ap.project_name, '锛�') AS player_name, stage.name AS activity_name, ap.project_name AS project_name, u.phone AS phone, ap.create_time AS apply_time, ap.state AS state, " +
+            "COALESCE(rating_stats.rating_count, 0) AS rating_count, rating_stats.average_score " +
+            "FROM t_activity_player ap " +
+            "JOIN t_player p ON p.id = ap.player_id " +
+            "JOIN t_user u ON u.id = p.user_id " +
+            "JOIN t_activity stage ON stage.id = ap.stage_id " +
+            "LEFT JOIN (" +
+            "  SELECT activity_player_id, COUNT(*) AS rating_count, AVG(total_score) AS average_score " +
+            "  FROM t_activity_player_rating " +
+            "  WHERE state = 1 " +
+            "  GROUP BY activity_player_id" +
+            ") rating_stats ON rating_stats.activity_player_id = ap.id ";
+        
+        StringBuilder whereClause = new StringBuilder();
+        boolean hasCondition = false;
+        
+        // 椤圭洰璇勫鏌ヨ锛氱洿鎺ユ牴鎹樁娈礗D鏌ヨ锛屼笖榛樿鍙煡璇㈠鏍搁�氳繃鐨勬暟鎹�
+        
+        if (name != null && !name.isEmpty()) {
+            if (hasCondition) {
+                whereClause.append(" AND ");
+            }
+            whereClause.append("p.name LIKE CONCAT('%', :name, '%')");
+            hasCondition = true;
+        }
+        
+        if (activityId != null) {
+            if (hasCondition) {
+                whereClause.append(" AND ");
+            }
+            // 鐩存帴鏌ヨ鎸囧畾闃舵ID鐨勬姤鍚嶉」鐩�
+            whereClause.append("ap.stage_id = :activityId");
+            hasCondition = true;
+        }
+
+        if (regionId != null) {
+            if (hasCondition) {
+                whereClause.append(" AND ");
+            }
+            whereClause.append("ap.region_id = :regionId");
+            hasCondition = true;
+        }
+        
+        // 榛樿鍙煡璇㈠鏍搁�氳繃鐨勬暟鎹� (state = 1)
+        if (hasCondition) {
+            whereClause.append(" AND ");
+        }
+        whereClause.append("ap.state = 1");
+        hasCondition = true;
+        
+        // 濡傛灉浼犲叆浜唖tate鍙傛暟锛屽垯瑕嗙洊榛樿鐨剆tate=1鏉′欢
+        if (state != null) {
+            // 绉婚櫎鏈�鍚庢坊鍔犵殑 "ap.state = 1" 鏉′欢
+            String whereStr = whereClause.toString();
+            whereStr = whereStr.replace(" AND ap.state = 1", "");
+            whereClause = new StringBuilder(whereStr);
+            
+            if (hasCondition && !whereStr.isEmpty()) {
+                whereClause.append(" AND ");
+            }
+            whereClause.append("ap.state = :state");
+        }
+        
+        String where = hasCondition ? "WHERE " + whereClause.toString() + " " : "";
+        String order = "ORDER BY ap.create_time DESC ";
+        String limit = "";
+        if (page != null && size != null && page > 0 && size > 0) {
+            int offset = (page - 1) * size;
+            limit = "LIMIT " + size + " OFFSET " + offset + " ";
+        }
+
+        var q = em.createNativeQuery(baseSql + where + order + limit);
+        if (name != null && !name.isEmpty()) {
+            q.setParameter("name", name);
+        }
+        if (activityId != null) {
+            q.setParameter("activityId", activityId);
+        }
+        if (regionId != null) {
+            q.setParameter("regionId", regionId);
+        }
+        if (state != null) {
+            q.setParameter("state", state);
+        }
+        List<Object[]> rows = q.getResultList();
+        List<ActivityPlayerApplicationResponse> list = new ArrayList<>();
+        for (Object[] r : rows) {
+            ActivityPlayerApplicationResponse dto = new ActivityPlayerApplicationResponse();
+            dto.setId(r[0] != null ? Long.valueOf(r[0].toString()) : null); // activity_player_id
+            dto.setPlayerName(r[1] != null ? r[1].toString() : "");
+            dto.setActivityName(r[2] != null ? r[2].toString() : "");
+            dto.setProjectName(r[3] != null ? r[3].toString() : ""); // project_name
+            dto.setPhone(r[4] != null ? r[4].toString() : "");
+            dto.setApplyTime(r[5] != null ? r[5].toString() : "");
+            // 鏄犲皠鐘舵�侊細浣跨敤 t_activity_player.state锛�0=鏈鏍革紝1=瀹℃牳閫氳繃锛�2=瀹℃牳椹冲洖锛�
+            dto.setState(r[6] != null ? Integer.valueOf(r[6].toString()) : 0);
+            // 鏄犲皠璇勫缁熻鏁版嵁
+            dto.setRatingCount(r[7] != null ? Integer.valueOf(r[7].toString()) : 0);
+            dto.setAverageScore(r[8] != null ? Double.valueOf(r[8].toString()) : null);
+            list.add(dto);
+        }
+        
+        // 鍒涘缓鍒嗛〉鍝嶅簲
+        long totalElements = list.size();
+        return new PageResponse<>(list, totalElements, page, size);
     }
 }
\ No newline at end of file

--
Gitblit v1.8.0