@ -4,12 +4,17 @@ import com.dsideal.base.DataEase.Model.DataEaseModel;
import com.dsideal.base.Util.LocalMysqlConnectUtil ;
import com.jfinal.plugin.activerecord.Db ;
import com.jfinal.plugin.activerecord.Record ;
import com.dsideal.base.Util.CallDeepSeek ;
import java.util.List ;
import java.util.Map ;
import java.util.Set ;
import java.util.LinkedHashSet ;
import java.util.ArrayList ;
import java.util.concurrent.CountDownLatch ;
import java.text.SimpleDateFormat ;
import java.util.Date ;
import cn.hutool.core.io.FileUtil ;
import java.io.File ;
public class TestMax32K {
private static final int MAX_CHUNK_SIZE = 30000 ; // 30K字符限制
@ -17,15 +22,182 @@ public class TestMax32K {
public static void main ( String [ ] args ) {
LocalMysqlConnectUtil . Init ( ) ;
// 直接调用生成综合报告
String report = generateComprehensiveReport ( ) ;
System . out . println ( "\n=== 最终报告 ===" ) ;
System . out . println ( report ) ;
}
/ * *
* 分 割 过 大 的 单 表 数 据
* /
private static List < String > splitLargeTable ( String tableName , Set < String > fieldNames ,
List < Record > allTableData , int maxSize ) {
List < String > chunks = new ArrayList < > ( ) ;
StringBuilder currentTableChunk = new StringBuilder ( ) ;
for ( Record dataRecord : allTableData ) {
Map < String , Object > columns = dataRecord . getColumns ( ) ;
StringBuilder rowData = new StringBuilder ( ) ;
rowData . append ( "[" ) ;
boolean first = true ;
for ( String fieldName : fieldNames ) {
if ( ! first ) rowData . append ( "," ) ;
Object value = columns . get ( fieldName ) ;
if ( value instanceof String ) {
rowData . append ( "\"" ) . append ( value ) . append ( "\"" ) ;
} else {
rowData . append ( value ) ;
}
first = false ;
}
rowData . append ( "]\n" ) ;
// 检查是否超过限制
if ( currentTableChunk . length ( ) + rowData . length ( ) > maxSize ) {
if ( currentTableChunk . length ( ) > 0 ) {
chunks . add ( currentTableChunk . toString ( ) ) ;
currentTableChunk = new StringBuilder ( ) ;
}
}
currentTableChunk . append ( rowData ) ;
}
if ( currentTableChunk . length ( ) > 0 ) {
chunks . add ( currentTableChunk . toString ( ) ) ;
}
return chunks ;
}
/ * *
* 获 取 分 块 数 据 的 方 法 ( 可 供 其 他 类 调 用 )
* /
public static String [ ] getDataChunks ( ) {
// 这里可以将main方法中的逻辑提取出来, 返回分块数据
// 为了简化,这里只是示例
return new String [ ] { "示例数据块1" , "示例数据块2" } ;
}
public static String generateComprehensiveReport ( ) {
String [ ] regions = { "文山州" , "楚雄州" } ;
String sql = "select table_name as TABLE_NAME from core_dataset_table where dataset_group_id in (select id from core_dataset_group where pid='1036317909951057920')" ;
List < Record > tableList = Db . use ( DataEaseModel . DB_NAME ) . find ( sql ) ;
// 使用字符串数组存储分块数据
// 获取分块数据
String [ ] dataChunks = getDataChunks ( regions , tableList ) ;
List < String > chunkAnalyses = new ArrayList < > ( ) ;
System . out . println ( "开始分析 " + dataChunks . length + " 个数据块..." ) ;
// 第一阶段:流式分析各个数据块
for ( int i = 0 ; i < dataChunks . length ; i + + ) {
final int chunkIndex = i ;
final StringBuilder chunkResult = new StringBuilder ( ) ;
final CountDownLatch latch = new CountDownLatch ( 1 ) ;
String prompt = "请对以下教育数据进行简要分析, 重点关注关键指标和趋势, 控制在500字以内: \n" + dataChunks [ i ] ;
System . out . println ( "\n=== 正在分析第 " + ( i + 1 ) + " 个数据块 ===" ) ;
CallDeepSeek . callDeepSeekStream ( prompt , new CallDeepSeek . SSEListener ( ) {
@Override
public void onData ( String data ) {
System . out . print ( data ) ;
chunkResult . append ( data ) ;
}
@Override
public void onComplete ( String fullResponse ) {
System . out . println ( "\n--- 第 " + ( chunkIndex + 1 ) + " 个数据块分析完成 ---\n" ) ;
chunkAnalyses . add ( chunkResult . toString ( ) ) ;
latch . countDown ( ) ;
}
@Override
public void onError ( String error ) {
System . err . println ( "分析第 " + ( chunkIndex + 1 ) + " 个数据块时出错: " + error ) ;
chunkAnalyses . add ( "分析失败: " + error ) ;
latch . countDown ( ) ;
}
} ) ;
try {
// 等待当前块分析完成
latch . await ( ) ;
Thread . sleep ( 1000 ) ; // 稍微延迟, 避免API调用过于频繁
} catch ( InterruptedException e ) {
System . err . println ( "等待分析结果时被中断: " + e . getMessage ( ) ) ;
}
}
// 第二阶段:流式生成综合报告
System . out . println ( "\n=== 开始生成综合分析报告 ===" ) ;
StringBuilder combinedAnalysis = new StringBuilder ( ) ;
combinedAnalysis . append ( "基于以下分块分析结果, 请生成一份完整的教育数据综合分析报告( 3000字以内) : \n\n" ) ;
for ( int i = 0 ; i < chunkAnalyses . size ( ) ; i + + ) {
combinedAnalysis . append ( "数据块" ) . append ( i + 1 ) . append ( "分析:\n" ) ;
combinedAnalysis . append ( chunkAnalyses . get ( i ) ) . append ( "\n\n" ) ;
}
final StringBuilder finalReport = new StringBuilder ( ) ;
final CountDownLatch finalLatch = new CountDownLatch ( 1 ) ;
CallDeepSeek . callDeepSeekStream ( combinedAnalysis . toString ( ) , new CallDeepSeek . SSEListener ( ) {
@Override
public void onData ( String data ) {
System . out . print ( data ) ;
finalReport . append ( data ) ;
}
@Override
public void onComplete ( String fullResponse ) {
System . out . println ( "\n\n=== 综合分析报告生成完成 ===" ) ;
// 保存报告到文件
try {
String timestamp = new SimpleDateFormat ( "yyyyMMdd_HHmmss" ) . format ( new Date ( ) ) ;
String fileName = "教育数据综合分析报告_" + timestamp + ".txt" ;
String filePath = "WebRoot/upload/" + fileName ;
FileUtil . writeString ( finalReport . toString ( ) , new File ( filePath ) , "UTF-8" ) ;
System . out . println ( "报告已保存到: " + filePath ) ;
} catch ( Exception e ) {
System . err . println ( "保存报告时出错: " + e . getMessage ( ) ) ;
}
finalLatch . countDown ( ) ;
}
@Override
public void onError ( String error ) {
System . err . println ( "生成综合报告时出错: " + error ) ;
finalReport . append ( "生成失败: " ) . append ( error ) ;
finalLatch . countDown ( ) ;
}
} ) ;
try {
finalLatch . await ( ) ;
} catch ( InterruptedException e ) {
System . err . println ( "等待最终报告时被中断: " + e . getMessage ( ) ) ;
}
return finalReport . toString ( ) ;
}
/ * *
* 提 取 数 据 分 块 逻 辑 为 独 立 方 法
* /
private static String [ ] getDataChunks ( String [ ] regions , List < Record > tableList ) {
List < String > dataChunks = new ArrayList < > ( ) ;
StringBuilder currentChunk = new StringBuilder ( ) ;
// 添加数据说明头部
String header = "数据说明: 以下是云南省教育数据的压缩格式\n" +
"格式: 表名 -> 字段列表 -> 数据行(数组格式)\n" +
"地区范围: " + String . join ( "," , regions ) + "\n\n" ;
@ -41,7 +213,7 @@ public class TestMax32K {
// 为每个地区收集数据
for ( String region : regions ) {
sql = "select * from `" + tableName + "` where `行政区划`=?" ;
String sql = "select * from `" + tableName + "` where `行政区划`=?" ;
List < Record > listContent = Db . use ( DataEaseModel . DB_NAME ) . find ( sql , region ) ;
if ( ! listContent . isEmpty ( ) ) {
@ -114,76 +286,6 @@ public class TestMax32K {
dataChunks . add ( currentChunk . toString ( ) ) ;
}
// 输出分块结果统计
System . out . println ( "总共分成 " + dataChunks . size ( ) + " 个数据块:" ) ;
for ( int i = 0 ; i < dataChunks . size ( ) ; i + + ) {
String chunk = dataChunks . get ( i ) ;
System . out . println ( "数据块 " + ( i + 1 ) + " 长度: " + chunk . length ( ) + " 字符" ) ;
}
// 返回分块数据数组供后续使用
String [ ] chunksArray = dataChunks . toArray ( new String [ 0 ] ) ;
// 示例:如何使用分块数据
System . out . println ( "\n=== 可以这样使用分块数据 ===" ) ;
for ( int i = 0 ; i < chunksArray . length ; i + + ) {
System . out . println ( "处理第 " + ( i + 1 ) + " 个数据块..." ) ;
// 这里可以调用DeepSeek API处理每个块
// String result = CallDeepSeek.callDeepSeek(chunksArray[i]);
System . out . println ( "块 " + ( i + 1 ) + " 内容预览: " +
chunksArray [ i ] . substring ( 0 , Math . min ( 200 , chunksArray [ i ] . length ( ) ) ) + "..." ) ;
}
}
/ * *
* 分 割 过 大 的 单 表 数 据
* /
private static List < String > splitLargeTable ( String tableName , Set < String > fieldNames ,
List < Record > allTableData , int maxSize ) {
List < String > chunks = new ArrayList < > ( ) ;
StringBuilder currentTableChunk = new StringBuilder ( ) ;
for ( Record dataRecord : allTableData ) {
Map < String , Object > columns = dataRecord . getColumns ( ) ;
StringBuilder rowData = new StringBuilder ( ) ;
rowData . append ( "[" ) ;
boolean first = true ;
for ( String fieldName : fieldNames ) {
if ( ! first ) rowData . append ( "," ) ;
Object value = columns . get ( fieldName ) ;
if ( value instanceof String ) {
rowData . append ( "\"" ) . append ( value ) . append ( "\"" ) ;
} else {
rowData . append ( value ) ;
}
first = false ;
}
rowData . append ( "]\n" ) ;
// 检查是否超过限制
if ( currentTableChunk . length ( ) + rowData . length ( ) > maxSize ) {
if ( currentTableChunk . length ( ) > 0 ) {
chunks . add ( currentTableChunk . toString ( ) ) ;
currentTableChunk = new StringBuilder ( ) ;
}
}
currentTableChunk . append ( rowData ) ;
}
if ( currentTableChunk . length ( ) > 0 ) {
chunks . add ( currentTableChunk . toString ( ) ) ;
}
return chunks ;
}
/ * *
* 获 取 分 块 数 据 的 方 法 ( 可 供 其 他 类 调 用 )
* /
public static String [ ] getDataChunks ( ) {
// 这里可以将main方法中的逻辑提取出来, 返回分块数据
// 为了简化,这里只是示例
return new String [ ] { "示例数据块1" , "示例数据块2" } ;
return dataChunks . toArray ( new String [ 0 ] ) ;
}
}